Skip to content

Commit fafed98

Browse files
committed
Add more performance optimizations + benchmarks
1 parent 502a191 commit fafed98

File tree

2 files changed

+26
-4
lines changed

2 files changed

+26
-4
lines changed

src/mystace/mustache_tree.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,12 @@ def get(self, key: str) -> t.Any:
5757
if key == ".":
5858
return self.context
5959

60-
# Split only once and cache
61-
keys = key.split(".")
60+
# Use iterator to avoid copying keys
61+
chain_iter = iter(key.split("."))
6262
curr_ctx = self.context
6363
parent_node = self.parent_context_node
6464

65-
first_key = keys[0]
65+
first_key = next(chain_iter)
6666

6767
# TODO I think this is where changes need to be made if we want to
6868
# support indexing and lambdas.
@@ -83,7 +83,7 @@ def get(self, key: str) -> t.Any:
8383
return None
8484

8585
# Loop through the rest
86-
for key in keys[1:]:
86+
for key in chain_iter:
8787
if isinstance(outer_context, list):
8888
try:
8989
int_key = int(key)

tests/test_speed.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,24 @@ def generate_test_case_long(n: int) -> TestCaseT:
3939
return template, names
4040

4141

42+
def generate_test_case_simple_variables(n: int) -> TestCaseT:
43+
"""Simple test case with just variable substitutions."""
44+
template = " ".join(f"{{{{var{i}}}}}" for i in range(n))
45+
data = {f"var{i}": f"value{i}" for i in range(n)}
46+
return template, data
47+
48+
49+
def generate_test_case_simple_sections(n: int) -> TestCaseT:
50+
"""Simple test case with basic sections."""
51+
template = ""
52+
data = {}
53+
for i in range(n):
54+
section_name = f"section{i}"
55+
template += f"{{{{#{section_name}}}}}content{{{{/{section_name}}}}}"
56+
data[section_name] = True
57+
return template, data
58+
59+
4260
def generate_test_case_nested(n: int) -> TestCaseT:
4361
fake = Faker()
4462

@@ -333,6 +351,8 @@ def render_function(_, obj):
333351
elif render_function_name == "mstache":
334352
import mstache
335353

354+
# mstache.render() uses a default LRU cache for tokenization
355+
# so repeated calls benefit from caching automatically
336356
render_function = mstache.render
337357
else:
338358
assert_never(render_function_name)
@@ -364,6 +384,8 @@ def render_function(_, obj):
364384
generate_test_case_nested,
365385
generate_test_case_long,
366386
generate_test_case_random(1),
387+
generate_test_case_simple_variables,
388+
generate_test_case_simple_sections,
367389
],
368390
)
369391
@pytest.mark.parametrize("render_function_name", t.get_args(RenderFunctionT))

0 commit comments

Comments
 (0)