mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 11:17:21 +00:00
Reduce time to reload yaml and check configuration (#38469)
* Reduce time to reload yaml and check configuration We spend a significant amount of time compiling templates that we have already compiled. Use an LRU cache to avoid re-compiling templates that we frequently use. * pylint * switch to WeakValueDictionary * preen
This commit is contained in:
parent
63403f894d
commit
62c664fbbd
@ -10,6 +10,7 @@ import random
|
||||
import re
|
||||
from typing import Any, Dict, Iterable, List, Optional, Union
|
||||
from urllib.parse import urlencode as urllib_urlencode
|
||||
import weakref
|
||||
|
||||
import jinja2
|
||||
from jinja2 import contextfilter, contextfunction
|
||||
@ -958,6 +959,7 @@ class TemplateEnvironment(ImmutableSandboxedEnvironment):
|
||||
"""Initialise template environment."""
|
||||
super().__init__()
|
||||
self.hass = hass
|
||||
self.template_cache = weakref.WeakValueDictionary()
|
||||
self.filters["round"] = forgiving_round
|
||||
self.filters["multiply"] = multiply
|
||||
self.filters["log"] = logarithm
|
||||
@ -1042,5 +1044,25 @@ class TemplateEnvironment(ImmutableSandboxedEnvironment):
|
||||
"""Test if attribute is safe."""
|
||||
return isinstance(obj, Namespace) or super().is_safe_attribute(obj, attr, value)
|
||||
|
||||
def compile(self, source, name=None, filename=None, raw=False, defer_init=False):
|
||||
"""Compile the template."""
|
||||
if (
|
||||
name is not None
|
||||
or filename is not None
|
||||
or raw is not False
|
||||
or defer_init is not False
|
||||
):
|
||||
# If there are any non-default keywords args, we do
|
||||
# not cache. In prodution we currently do not have
|
||||
# any instance of this.
|
||||
return super().compile(source, name, filename, raw, defer_init)
|
||||
|
||||
cached = self.template_cache.get(source)
|
||||
|
||||
if cached is None:
|
||||
cached = self.template_cache[source] = super().compile(source)
|
||||
|
||||
return cached
|
||||
|
||||
|
||||
_NO_HASS_ENV = TemplateEnvironment(None)
|
||||
|
@ -1885,3 +1885,30 @@ def test_urlencode(hass):
|
||||
hass,
|
||||
)
|
||||
assert tpl.async_render() == "the%20quick%20brown%20fox%20%3D%20true"
|
||||
|
||||
|
||||
async def test_cache_garbage_collection():
|
||||
"""Test caching a template."""
|
||||
template_string = (
|
||||
"{% set dict = {'foo': 'x&y', 'bar': 42} %} {{ dict | urlencode }}"
|
||||
)
|
||||
tpl = template.Template((template_string),)
|
||||
tpl.ensure_valid()
|
||||
assert template._NO_HASS_ENV.template_cache.get(
|
||||
template_string
|
||||
) # pylint: disable=protected-access
|
||||
|
||||
tpl2 = template.Template((template_string),)
|
||||
tpl2.ensure_valid()
|
||||
assert template._NO_HASS_ENV.template_cache.get(
|
||||
template_string
|
||||
) # pylint: disable=protected-access
|
||||
|
||||
del tpl
|
||||
assert template._NO_HASS_ENV.template_cache.get(
|
||||
template_string
|
||||
) # pylint: disable=protected-access
|
||||
del tpl2
|
||||
assert not template._NO_HASS_ENV.template_cache.get(
|
||||
template_string
|
||||
) # pylint: disable=protected-access
|
||||
|
Loading…
x
Reference in New Issue
Block a user