From cf4a4ea68eca91aa044556806d3d91369182702c Mon Sep 17 00:00:00 2001 From: natsuoto <279971144+natsuoto@users.noreply.github.com> Date: Wed, 15 Jul 2026 18:12:42 +0530 Subject: =?UTF-8?q?chore:=20codebase-wide=20rule=20audit=20=E2=80=94=20eli?= =?UTF-8?q?minate=20Any/object=20where=20non-protocol,=20hoist=20in-functi?= =?UTF-8?q?on=20imports,=20rename=20compound/folder-repeat=20files,=20repl?= =?UTF-8?q?ace=20generic-exception=20raises,=20bind=20chained=20comprehens?= =?UTF-8?q?ions,=20strip=20=5F=5Finit=5F=5F=20docstrings,=20remove=20pragm?= =?UTF-8?q?as?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/builder/cache.test.py | 58 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) (limited to 'tests/builder/cache.test.py') diff --git a/tests/builder/cache.test.py b/tests/builder/cache.test.py index 700a8e4..045e8e9 100644 --- a/tests/builder/cache.test.py +++ b/tests/builder/cache.test.py @@ -1,8 +1,33 @@ -"""Tests for the per-instance lazy compile cache.""" +"""Tests for the per-instance lazy compile cache — semantics and cold/warm ratio.""" + +import time from edify import Pattern, RegexBuilder +def _hex_number_builder(): + return ( + RegexBuilder() + .start_of_input() + .assert_ahead() + .any_of("0x", "0o", "0b") + .end() + .capture() + .any_of("0x", "0o", "0b") + .end() + .between(1, 16) + .any_of_chars("0123456789abcdefABCDEF") + .end_of_input() + ) + + +def _measure_call_wall_clock(action, iterations): + start = time.perf_counter() + for _ in range(iterations): + action() + return time.perf_counter() - start + + def test_two_no_kwargs_to_regex_calls_return_the_same_instance(): builder = RegexBuilder().one_or_more().digit() first = builder.to_regex() @@ -61,3 +86,34 @@ def test_chain_step_yields_a_fresh_cache_slot(): def test_pattern_also_caches_across_repeat_to_regex_calls(): pattern = Pattern().string("hi") assert pattern.to_regex() is pattern.to_regex() + + +def test_warm_to_regex_is_at_least_ten_times_cheaper_than_cold_to_regex(): + warm_iterations = 200 + cold_iterations = 200 + + cold_total = 0.0 + for _ in range(cold_iterations): + builder = _hex_number_builder() + cold_start = time.perf_counter() + builder.to_regex() + cold_total += time.perf_counter() - cold_start + + warm_builder = _hex_number_builder() + warm_builder.to_regex() + warm_total = _measure_call_wall_clock(warm_builder.to_regex, warm_iterations) + + average_cold = cold_total / cold_iterations + average_warm = warm_total / warm_iterations + + assert average_warm * 10 < average_cold, ( + f"cache ratio too weak: warm={average_warm * 1e6:.2f}µs, " + f"cold={average_cold * 1e6:.2f}µs — warm should be < cold / 10." + ) + + +def test_repeat_to_regex_returns_the_same_regex_instance(): + warm_builder = _hex_number_builder() + first = warm_builder.to_regex() + second = warm_builder.to_regex() + assert first is second -- cgit v1.2.3