Repository navigation
perf(entity_quality): 2x faster validate_entity_slug for repair plans - #274
Merged
jack-arturo merged 1 commit intoNov 2, 2026
Merged
Conversation
Split the canonical slug once in validate_entity_slug and pass the parts to the private helpers instead of re-splitting it in each one. Look up action-status roots by removing known suffixes, skip the slugify regex for clean stored slugs, check people vocabulary with isdisjoint, and return early before regex calls that cannot match. Output is unchanged. build_repair_plan(mode="canonicalize-safe") on 708 mixed entity:people rows drops from 72.6 ms to 35.1 ms per call. pytest tests: 953 passed, 12 skipped. Co-Authored-By: Aiden <aiden@weco.ai>
Member
|
Thanks @dexhunter :) |
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.
TL;DR
automem/utils/entity_quality.pyfaster (validate_entity_slugand its private helpers).build_repair_plancall on 708 rows takes 72.6 ms before and 35.1 ms after (median), 51.6% faster.pytest testsgives 953 passed, 12 skipped, the same as ondevelop.What & Why
build_repair_plancallsvalidate_entity_tagfor every entity tag. Before this change, each check split the same slug again. The action-status check also built a new set of word forms for every root. The people check ran a regex on each part and seven membership tests per part.Now
validate_entity_slugsplits the canonical slug once and passes the parts list to each helper. The action-status check removes each known suffix and looks up the root directly. Clean stored slugs skip the slugify regex. Cheap length or first-character checks run before regex calls that cannot match. The vocabulary check usesisdisjointon each vocabulary set.The output stays identical. Each shortcut only skips work when the old code would give the same answer. The same rejection reasons are returned in the same order, and
_accepted()/_reject()still build every result.Changes
validate_entity_slug: split the canonical slug once and pass the parts to the helpers._looks_like_action_status_slug: undo each inflection (-s,-ed,-d,-ing,-ied) and look up the root once._looks_like_unicode_escape_slugand the people name check: use one regex over the whole slug._looks_like_duration_or_count_slug,_looks_like_generated_fragment_slug,_has_internal_camelcase: return early when a pattern cannot match.isdisjointfor each vocabulary set instead of sevenintests per part._looks_tool_or_org_like: pass the whole suffix tuple to oneendswithcall.No public API, configuration or docs change. Only private helper signatures change, and only
validate_entity_slugcalls them.Results
Median of 5 alternating runs on an isolated CPU core (Python 3.12):
build_repair_plan, 708 benchmark rowsbuild_repair_plan, 8 rows from the existing testentity:peopletagsentity:peopletagsentity:peopletags (rejected)Why this is safe and easy to maintain
The change is small and stays in one file. It keeps the existing regular expressions and the
_accepted()/_reject()builders. Behaviour and output are unchanged: 200,000 random slugs, categories and tags give identical results before and after.tests/test_entity_quality.py,tests/test_repair_entity_tags.pyandtests/test_entity_identities.pycover these paths.Validation
pytest tests/test_entity_quality.py tests/test_repair_entity_tags.py tests/test_entity_identities.py: 165 passed.pytest tests: 953 passed, 12 skipped (same asdevelop).black --check,isort --checkand the CIflake8selection pass on the changed file.build_repair_plan(rows, mode="canonicalize-safe")on 708 rows of mixedentity:peopletags (the four rows oftest_plan_suppresses_single_name_people_unsafe_structural_targetsplus 700 generated rows). Before: 72.6 ms per call. After: 35.1 ms per call (224 ms -> 111 ms for 3 calls). Three repeated measurements gave 0.496, 0.502 and 0.492 of the old time.No linked issue.
AI assistance
This PR was prepared with AI assistance from Aiden. Candidates were tracked with Weco Observe.
Weco share link: https://dashboard.weco.ai/share/yYsMiWbvWBbxNasQaArg0DiL0pH8MxX2