Reduce overhead to lookup items in the entity and device registry (#94568)

This commit is contained in:
J. Nick Koston 2023-06-14 08:47:18 -10:00 committed by GitHub
parent de62082605
commit a0c023d5cb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 35 additions and 6 deletions

View file

@ -292,6 +292,7 @@ class DeviceRegistry:
devices: DeviceRegistryItems[DeviceEntry]
deleted_devices: DeviceRegistryItems[DeletedDeviceEntry]
_device_data: dict[str, DeviceEntry]
def __init__(self, hass: HomeAssistant) -> None:
"""Initialize the device registry."""
@ -306,8 +307,12 @@ class DeviceRegistry:
@callback
def async_get(self, device_id: str) -> DeviceEntry | None:
"""Get device."""
return self.devices.get(device_id)
"""Get device.
We retrieve the DeviceEntry from the underlying dict to avoid
the overhead of the UserDict __getitem__.
"""
return self._device_data.get(device_id)
@callback
def async_get_device(
@ -641,6 +646,7 @@ class DeviceRegistry:
self.devices = devices
self.deleted_devices = deleted_devices
self._device_data = devices.data
@callback
def async_schedule_save(self) -> None:

View file

@ -425,6 +425,7 @@ class EntityRegistry:
"""Class to hold a registry of entities."""
entities: EntityRegistryItems
_entities_data: dict[str, RegistryEntry]
def __init__(self, hass: HomeAssistant) -> None:
"""Initialize the registry."""
@ -470,8 +471,12 @@ class EntityRegistry:
@callback
def async_get(self, entity_id: str) -> RegistryEntry | None:
"""Get EntityEntry for an entity_id."""
return self.entities.get(entity_id)
"""Get EntityEntry for an entity_id.
We retrieve the RegistryEntry from the underlying dict to avoid
the overhead of the UserDict __getitem__.
"""
return self._entities_data.get(entity_id)
@callback
def async_get_entity_id(
@ -991,6 +996,7 @@ class EntityRegistry:
)
self.entities = entities
self._entities_data = entities.data
@callback
def async_schedule_save(self) -> None:

View file

@ -509,6 +509,7 @@ def mock_registry(
if mock_entries is None:
mock_entries = {}
registry.entities = er.EntityRegistryItems()
registry._entities_data = registry.entities.data
for key, entry in mock_entries.items():
registry.entities[key] = entry
@ -554,6 +555,7 @@ def mock_device_registry(
"""
registry = dr.DeviceRegistry(hass)
registry.devices = dr.DeviceRegistryItems()
registry._device_data = registry.devices.data
if mock_entries is None:
mock_entries = {}
for key, entry in mock_entries.items():

View file

@ -1644,7 +1644,6 @@ async def test_homekit_ignored_missing_devices(
light = entity_registry.async_get_or_create(
"light", "powerwall", "demo", device_id=device_entry.id
)
before_removal = entity_registry.entities.copy()
# Delete the device to make sure we fallback
# to using the platform
device_registry.async_remove_device(device_entry.id)
@ -1652,7 +1651,23 @@ async def test_homekit_ignored_missing_devices(
await asyncio.sleep(0)
await asyncio.sleep(0)
# Restore the registry
entity_registry.entities = before_removal
entity_registry.async_get_or_create(
"binary_sensor",
"powerwall",
"battery_charging",
device_id=device_entry.id,
original_device_class=BinarySensorDeviceClass.BATTERY_CHARGING,
)
entity_registry.async_get_or_create(
"sensor",
"powerwall",
"battery",
device_id=device_entry.id,
original_device_class=SensorDeviceClass.BATTERY,
)
light = entity_registry.async_get_or_create(
"light", "powerwall", "demo", device_id=device_entry.id
)
hass.states.async_set(light.entity_id, STATE_ON)
hass.states.async_set("light.two", STATE_ON)