feat: improve performance of constructing ServiceInfo (#1141) · python-zeroconf/python-zeroconf@36d5b45
@@ -23,6 +23,7 @@
2323import ipaddress
2424import random
2525import socket
26+from functools import lru_cache
2627from typing import TYPE_CHECKING, Any, Dict, List, Optional, Set, Union, cast
27282829from .._dns import (
@@ -79,6 +80,9 @@ def instance_name_from_service_info(info: "ServiceInfo") -> str:
7980return info.name[: -len(service_name) - 1]
8081818283+_cached_ip_addresses = lru_cache(maxsize=256)(ipaddress.ip_address)
84+85+8286class ServiceInfo(RecordUpdateListener):
8387"""Service information.
8488@@ -196,7 +200,7 @@ def addresses(self, value: List[bytes]) -> None:
196200197201for address in value:
198202try:
199-addr = ipaddress.ip_address(address)
203+addr = _cached_ip_addresses(address)
200204except ValueError:
201205raise TypeError(
202206"Addresses must either be IPv4 or IPv6 strings, bytes, or integers;"
@@ -245,7 +249,7 @@ def parsed_scoped_addresses(self, version: IPVersion = IPVersion.All) -> List[st
245249return self.parsed_addresses(version)
246250247251def is_link_local(addr_str: str) -> Any:
248-addr = ipaddress.ip_address(addr_str)
252+addr = _cached_ip_addresses(addr_str)
249253return addr.version == 6 and addr.is_link_local
250254251255ll_addrs = list(filter(is_link_local, self.parsed_addresses(version)))
@@ -346,7 +350,7 @@ def _process_record_threadsafe(self, record: DNSRecord, now: float) -> None:
346350if record.key != self.server_key:
347351return
348352try:
349-ip_addr = ipaddress.ip_address(record.address)
353+ip_addr = _cached_ip_addresses(record.address)
350354except ValueError as ex:
351355log.warning("Encountered invalid address while processing %s: %s", record, ex)
352356return