diff options
Diffstat (limited to 'tests/builder/cache.test.py')
| -rw-r--r-- | tests/builder/cache.test.py | 58 |
1 files changed, 57 insertions, 1 deletions
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 |
