Skip to content

[PHPUnit60] Cache containsAssertCall() per node in AddDoesNotPerformAssertionToNonAssertingTestRector - #829

Merged
TomasVotruba merged 3 commits into
mainfrom
tv-assert-call-cache-perf
Nov 14, 2026
Merged

TomasVotruba merged 3 commits into
mainfrom
tv-assert-call-cache-perf

Conversation

@TomasVotruba

@TomasVotruba TomasVotruba commented Nov 14, 2026 •

Copy link
Copy Markdown
Member

Follow-up to #826.

Change

  • containsAssertCall() cache: the key was md5(prettyPrint(method) . className), so the whole method was printed on every call. The result is now stored as a node attribute. Identical bodies in different classes don't share a result, without needing the class name in the key. A node attribute instead of WeakMap, so the code still downgrades to PHP 7.4.
  • parent::method() now checks the class that declares the method, not only the direct parent. Before, parent::setUp() through a parent that doesn't override it was resolved up to TestCase, which then had to be parsed.

Bench

New bench/does_not_perform_assertion_cache_bench.php: 300 test classes calling helpers from 5 abstract parents, plus a parent::setUp() call declared only in TestCase. Fails above 1.0 s CPU.

CPU, 3 runs, local PHP 8.5 (busy machine, CI is ~3x faster), vs main at 9545637:

main this PR
does_not_perform_assertion_cache_bench.php 2.09-2.28 s 1.46-1.52 s
does_not_perform_assertion_lifecycle_bench.php 1.26-1.28 s 1.04-1.13 s
does_not_perform_assertion_abstract_class_bench.php 0.16-0.17 s 0.12-0.16 s
does_not_perform_assertion_own_lifecycle_bench.php 0.23-0.24 s 0.18-0.19 s
does_not_perform_assertion_framework_test_case_bench.php 0.49-0.53 s 0.39-0.44 s

Most of the remaining time is parsing each parent file once. That work is required: before #826, main skipped it only because of the shared cache entry.

Trade-off

The cached result stays on the node for the rest of the run. If another rule later adds an assert inside a method that was already checked, the cached value is out of date.

@TomasVotruba
TomasVotruba force-pushed the tv-assert-call-cache-perf branch 2 times, most recently from 2f1b501 to 41acd50 Compare November 14, 2026 20:03
…ssertionToNonAssertingTestRector

The cache key printed the whole method body on every call. Store the result as a node attribute instead - same body in different classes no longer shares a result, and no printing is needed.

"parent::method()" now checks the class that declares the method, so a method inherited from TestCase through a parent that does not override it is skipped too, instead of parsing TestCase.

Add bench/does_not_perform_assertion_cache_bench.php to cover both.
@TomasVotruba
TomasVotruba force-pushed the tv-assert-call-cache-perf branch from 1557b8e to 5eed414 Compare November 14, 2026 20:55
@TomasVotruba
TomasVotruba merged commit 6d45a51 into main Nov 14, 2026
13 checks passed
@TomasVotruba
TomasVotruba deleted the tv-assert-call-cache-perf branch November 14, 2026 20:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant