Small performance improvements to collecting analytics (#110662)

- Use async_entity_ids_count instead of async_all

I also tried to make the code wrap a bit less but
I didn't want to refactor it to much in this PR

This one blocks the event loop for just a bit so there
are probably some more parts that could be optimized

`2024-02-15 07:17:30.034 WARNING (MainThread) [asyncio] Executing <Task
pending name='analytics schedule' coro=<Analytics.send_analytics()
running at
/usr/src/homeassistant/homeassistant/components/analytics/analytics.py:220>
wait_for=<Future pending cb=[_chain_future.<locals>._call_check_cancel()
at /usr/local/lib/python3.12/asyncio/futures.py:387, Task.task_wakeup()]
created at /usr/local/lib/python3.12/asyncio/base_events.py:447>
cb=[set.remove()] created at
/usr/src/homeassistant/homeassistant/core.py:598> took 0.335 seconds`
This commit is contained in:
J. Nick Koston 2024-02-16 05:23:11 -06:00 committed by GitHub
parent 0aaa517217
commit 66f189ef26
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -173,6 +173,7 @@ class Analytics:
async def send_analytics(self, _: datetime | None = None) -> None: async def send_analytics(self, _: datetime | None = None) -> None:
"""Send analytics.""" """Send analytics."""
hass = self.hass
supervisor_info = None supervisor_info = None
operating_system_info: dict[str, Any] = {} operating_system_info: dict[str, Any] = {}
@ -185,10 +186,10 @@ class Analytics:
await self._store.async_save(dataclass_asdict(self._data)) await self._store.async_save(dataclass_asdict(self._data))
if self.supervisor: if self.supervisor:
supervisor_info = hassio.get_supervisor_info(self.hass) supervisor_info = hassio.get_supervisor_info(hass)
operating_system_info = hassio.get_os_info(self.hass) or {} operating_system_info = hassio.get_os_info(hass) or {}
system_info = await async_get_system_info(self.hass) system_info = await async_get_system_info(hass)
integrations = [] integrations = []
custom_integrations = [] custom_integrations = []
addons = [] addons = []
@ -214,10 +215,10 @@ class Analytics:
if self.preferences.get(ATTR_USAGE, False) or self.preferences.get( if self.preferences.get(ATTR_USAGE, False) or self.preferences.get(
ATTR_STATISTICS, False ATTR_STATISTICS, False
): ):
ent_reg = er.async_get(self.hass) ent_reg = er.async_get(hass)
try: try:
yaml_configuration = await conf_util.async_hass_config_yaml(self.hass) yaml_configuration = await conf_util.async_hass_config_yaml(hass)
except HomeAssistantError as err: except HomeAssistantError as err:
LOGGER.error(err) LOGGER.error(err)
return return
@ -229,8 +230,8 @@ class Analytics:
if not entity.disabled if not entity.disabled
} }
domains = async_get_loaded_integrations(self.hass) domains = async_get_loaded_integrations(hass)
configured_integrations = await async_get_integrations(self.hass, domains) configured_integrations = await async_get_integrations(hass, domains)
enabled_domains = set(configured_integrations) enabled_domains = set(configured_integrations)
for integration in configured_integrations.values(): for integration in configured_integrations.values():
@ -261,7 +262,7 @@ class Analytics:
if supervisor_info is not None: if supervisor_info is not None:
installed_addons = await asyncio.gather( installed_addons = await asyncio.gather(
*( *(
hassio.async_get_addon_info(self.hass, addon[ATTR_SLUG]) hassio.async_get_addon_info(hass, addon[ATTR_SLUG])
for addon in supervisor_info[ATTR_ADDONS] for addon in supervisor_info[ATTR_ADDONS]
) )
) )
@ -276,7 +277,7 @@ class Analytics:
) )
if self.preferences.get(ATTR_USAGE, False): if self.preferences.get(ATTR_USAGE, False):
payload[ATTR_CERTIFICATE] = self.hass.http.ssl_certificate is not None payload[ATTR_CERTIFICATE] = hass.http.ssl_certificate is not None
payload[ATTR_INTEGRATIONS] = integrations payload[ATTR_INTEGRATIONS] = integrations
payload[ATTR_CUSTOM_INTEGRATIONS] = custom_integrations payload[ATTR_CUSTOM_INTEGRATIONS] = custom_integrations
if supervisor_info is not None: if supervisor_info is not None:
@ -284,11 +285,11 @@ class Analytics:
if ENERGY_DOMAIN in enabled_domains: if ENERGY_DOMAIN in enabled_domains:
payload[ATTR_ENERGY] = { payload[ATTR_ENERGY] = {
ATTR_CONFIGURED: await energy_is_configured(self.hass) ATTR_CONFIGURED: await energy_is_configured(hass)
} }
if RECORDER_DOMAIN in enabled_domains: if RECORDER_DOMAIN in enabled_domains:
instance = get_recorder_instance(self.hass) instance = get_recorder_instance(hass)
engine = instance.database_engine engine = instance.database_engine
if engine and engine.version is not None: if engine and engine.version is not None:
payload[ATTR_RECORDER] = { payload[ATTR_RECORDER] = {
@ -297,9 +298,9 @@ class Analytics:
} }
if self.preferences.get(ATTR_STATISTICS, False): if self.preferences.get(ATTR_STATISTICS, False):
payload[ATTR_STATE_COUNT] = len(self.hass.states.async_all()) payload[ATTR_STATE_COUNT] = hass.states.async_entity_ids_count()
payload[ATTR_AUTOMATION_COUNT] = len( payload[ATTR_AUTOMATION_COUNT] = hass.states.async_entity_ids_count(
self.hass.states.async_all(AUTOMATION_DOMAIN) AUTOMATION_DOMAIN
) )
payload[ATTR_INTEGRATION_COUNT] = len(integrations) payload[ATTR_INTEGRATION_COUNT] = len(integrations)
if supervisor_info is not None: if supervisor_info is not None:
@ -307,7 +308,7 @@ class Analytics:
payload[ATTR_USER_COUNT] = len( payload[ATTR_USER_COUNT] = len(
[ [
user user
for user in await self.hass.auth.async_get_users() for user in await hass.auth.async_get_users()
if not user.system_generated if not user.system_generated
] ]
) )