perf: cache JSONPriorConfig lookups (model deserialization -44%) - #130
Merged
Conversation
path_value_tuples re-sorted the whole flattened config on EVERY
lookup (the map was cached, the sort was not) and __call__ then
linear-scanned it, with identical queries repeating for every prior
of every model construction. Cache the sorted tuples and memoize
lookups per instance, including misses (the class-family probe in
for_class_and_suffix_path relies on repeated expected misses).
Fresh instances per config push = natural invalidation; returned
sub-dicts were already aliased across calls.
Measured on the aggregator harness: values("model") 8.15 -> 4.60
ms/result (-44%); summaries -25%. Benefits every Model construction.
Aggregator-arc deeper follow-up (#129).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The aggregator arc's recorded "deeper follow-up" (#129): cProfile showed 77% of per-result summary/model deserialization is
Model.__init__building default priors from prior config, and most of that was two defects inJSONPriorConfig:path_value_tuplesre-sorted the entire flattened config dict on every lookup — the flattened map was cached, the sort was not.__call__then linear-scanned the tuples, with identical queries repeating for every prior of every model construction (thousands of times when aggregating a catalogue).Fix: cache the sorted tuples and memoize lookups per instance — including misses, which the class-family probe in
for_class_and_suffix_pathperforms repeatedly by design (a_NOT_FOUNDsentinel; found-Noneis also representable). Invalidation is structural: config pushes construct freshJSONPriorConfiginstances, and returned sub-dicts were already aliased across repeated calls, so no new sharing is introduced.Measured (100 mock results, like-for-like load, best of 3):
values("model"): 8.15 → 4.60 ms/result (−44%)values("samples_summary"): 8.73 → 6.58 ms/result (−25%; includes sample-json costs the cache doesn't touch)This benefits every
Model/Collectionconstruction (search startup included), not just the aggregator.API Changes
None — internal caching only; lookup results and exception behaviour are unchanged.
Test Plan
pytest test_autoconf— 147 passed (+ new cache regression test: repeated hits and repeated misses)pytest test_autofit/— 1495 passed, 1 skippedGenerated by the PyAutoLabs agent workflow.