From 3d385796da53b4f3036fdc392db890257f8a3c72 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 17 Jun 2020 15:23:42 -0500 Subject: [PATCH] Improve logbook performance when no entities are filtered (#36842) Various tweaks to reduce the python overhead of the lazy class --- homeassistant/components/logbook/__init__.py | 58 ++++++++++---------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/homeassistant/components/logbook/__init__.py b/homeassistant/components/logbook/__init__.py index 6309b7c970c..d970959ca39 100644 --- a/homeassistant/components/logbook/__init__.py +++ b/homeassistant/components/logbook/__init__.py @@ -377,7 +377,7 @@ def _get_events(hass, config, start_day, end_day, entity_id=None): def yield_events(query): """Yield Events that are not filtered away.""" - for row in query.yield_per(500): + for row in query.yield_per(1000): event = LazyEventPartialState(row) if _keep_event(hass, event, entities_filter): yield event @@ -385,8 +385,10 @@ def _get_events(hass, config, start_day, end_day, entity_id=None): with session_scope(hass=hass) as session: if entity_id is not None: entity_ids = [entity_id.lower()] - else: + elif config.get(CONF_EXCLUDE) or config.get(CONF_INCLUDE): entity_ids = _get_related_entity_ids(session, entities_filter) + else: + entity_ids = None query = ( session.query( @@ -404,14 +406,21 @@ def _get_events(hass, config, start_day, end_day, entity_id=None): Events.event_type.in_(ALL_EVENT_TYPES + list(hass.data.get(DOMAIN, {}))) ) .filter((Events.time_fired > start_day) & (Events.time_fired < end_day)) - .filter( + ) + + if entity_ids: + query = query.filter( ( (States.last_updated == States.last_changed) & States.entity_id.in_(entity_ids) ) | (States.state_id.is_(None)) ) - ) + else: + query = query.filter( + (States.last_updated == States.last_changed) + | (States.state_id.is_(None)) + ) prev_states = {} return list(humanify(hass, yield_events(query), prev_states)) @@ -425,7 +434,6 @@ def _get_attribute(hass, entity_id, event, attribute): def _keep_event(hass, event, entities_filter): - entity_id = None if event.event_type == EVENT_STATE_CHANGED: entity_id = event.entity_id @@ -444,20 +452,18 @@ def _keep_event(hass, event, entities_filter): elif event.event_type == EVENT_LOGBOOK_ENTRY: event_data = event.data domain = event_data.get(ATTR_DOMAIN) - + entity_id = None elif event.event_type in hass.data.get(DOMAIN, {}) and not event.data.get( "entity_id" ): # If the entity_id isn't described, use the domain that describes # the event for filtering. domain = hass.data[DOMAIN][event.event_type][0] - + entity_id = None else: event_data = event.data domain = event_data.get(ATTR_DOMAIN) entity_id = event_data.get("entity_id") - if entity_id: - domain = split_entity_id(entity_id)[0] if not entity_id and domain: entity_id = f"{domain}." @@ -556,18 +562,25 @@ def _entry_message_from_event(hass, entity_id, domain, event): class LazyEventPartialState: """A lazy version of core Event with limited State joined in.""" - __slots__ = ["_row", "_event_data", "_time_fired"] + __slots__ = [ + "_row", + "_event_data", + "_time_fired", + "event_type", + "entity_id", + "state", + "domain", + ] def __init__(self, row): """Init the lazy event.""" self._row = row self._event_data = None self._time_fired = None - - @property - def event_type(self): - """Type of event.""" - return self._row.event_type + self.event_type = self._row.event_type + self.entity_id = self._row.entity_id + self.state = self._row.state + self.domain = self._row.domain @property def context_user_id(self): @@ -617,18 +630,3 @@ class LazyEventPartialState: .get(ATTR_HIDDEN, False) ) return False - - @property - def entity_id(self): - """Entity id that changed state.""" - return self._row.entity_id - - @property - def domain(self): - """Domain of the entity_id that changed state.""" - return self._row.domain - - @property - def state(self): - """State of the entity_id that changed state.""" - return self._row.state