perf(paths): memoize is_absolute_any_platform, skip Path construction on the POSIX arm - #3615
abhay-codes07 wants to merge 1 commit into
Conversation
… on the POSIX arm
The pipeline asks is_absolute_any_platform of the same few hundred stored
paths tens of thousands of times — once or more per node/edge in build, again
per resolution pass — and each uncached call built TWO pathlib objects (a
PurePosixPath and a PureWindowsPath) just to read one flag. It is now memoized
(a pure function of the string; nothing touches the filesystem, so no
staleness), with the POSIX arm reduced to its exact equivalent s.startswith("/")
and checked first so a common in-repo relative path returns without
constructing any Path — PureWindowsPath is built only for the drive/UNC forms
the cheap check cannot settle. ~20x faster on the repeated-path pattern
(14.3ms -> 0.7ms per 10k calls). Semantics are byte-identical: verified with
zero mismatches against the prior implementation across 12k+ generated path
forms (POSIX roots, drive letters, UNC, mixed separators, None/empty).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JJbLfztSxm2tH5cJwBbe9q
There was a problem hiding this comment.
Graphify reviewed this change.
Looks safe to merge — no coupling regressions and no blocking issues, checked against the code graph (not a self-assessment).
Formal verification. No changes could be formally verified in this run.
Graphify review — findings
Memoizes is_absolute_any_platform behind a cached _is_absolute_any_platform_str that checks s.startswith("/") before falling back to a PureWindowsPath, avoiding the two pathlib objects the old two-arm check built on every call. The None/empty guard still short-circuits ahead of the cache, so those never occupy an entry. Results stay byte-for-byte identical to the prior PurePosixPath(...) or PureWindowsPath(...), backed by edge-case, fuzz, and cache-hit tests.
No blocking issues surfaced.
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 2193 functions depend on the 40 functions this change touches.
Health — this change adds coupling hotspots:
- new:
extract()— 645 callers, 45 callees - new:
_rebuild_code()— 129 callers, 54 callees - new:
build_from_json()— 214 callers, 20 callees - new:
build_merge()— 76 callers, 14 callees - new:
save_semantic_cache()— 63 callers, 9 callees - new:
to_obsidian()— 38 callers, 14 callees - new:
save_manifest()— 40 callers, 11 callees - new:
to_json()— 56 callers, 7 callees - …and 58 more — each is listed as a finding
Verification — 2193 functions in the blast radius were not formally verified this run (proofs are advisory here).
Gate & verification
graphify gate
PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.
Advisory (not blocking):
- verification_scope: 1234 function(s) in the blast radius were not formally verified this run
Test selection
Test selection
113 of 287 test file(s) selected (39%) via static blast radius.
tests/test_affected_cli.py— impacttests/test_agents_platform.py— impacttests/test_analyze.py— impacttests/test_atomic_canvas_export.py— impacttests/test_atomic_version_stamp.py— impacttests/test_atomic_writes.py— impacttests/test_benchmark.py— impacttests/test_benchmark_raw_graph.py— impacttests/test_build.py— impacttests/test_build_merge_dedup_scope.py— impacttests/test_build_merge_hyperedges_and_prune.py— impacttests/test_build_merge_shrink_guard.py— impacttests/test_cache.py— impacttests/test_callflow_html.py— impacttests/test_carried_hyperedge_remap.py— impacttests/test_charmap_encoding.py— impacttests/test_chunking.py— impacttests/test_cli_export.py— impacttests/test_cluster.py— impacttests/test_codebuddy.py— impacttests/test_community_labels_skill.py— impacttests/test_confidence.py— impacttests/test_corrupt_graph_json.py— impacttests/test_cpp_objc_cross_file_calls.py— impacttests/test_cross_extension_reexport_self_cycle.py— impacttests/test_dedup.py— impacttests/test_dedup_remaps_hyperedges.py— impacttests/test_definition_file_portability.py— impacttests/test_detect.py— impacttests/test_devin.py— impacttests/test_duplicate_annotation_edges.py— impacttests/test_evidence_binding.py— impacttests/test_explain_cli.py— impacttests/test_export.py— impacttests/test_export_control_characters.py— impacttests/test_export_path_length.py— impacttests/test_external_stub_endpoints.py— impacttests/test_extract.py— impacttests/test_extract_cache_location.py— impacttests/test_extract_cli.py— impacttests/test_falkordb_integration.py— impacttests/test_file_label_disambiguation.py— impacttests/test_global_add_tag_inference.py— impacttests/test_global_graph.py— impacttests/test_go_qualified_resolution.py— impacttests/test_god_nodes_cli.py— impacttests/test_god_nodes_exclude_hubs.py— impacttests/test_hollow_chunks_arm_shrink_guard.py— impacttests/test_hook_out_of_project_paths.py— impacttests/test_hook_strict.py— impact- … and 63 more
Selection is safe under the controlled-regression assumption; always-run tests + a periodic full run are the backstops. Advisory — it never changes the check verdict.
Formal verification
Could not verify: Could not verify is\_absolute\_any\_platform.
The verifier did not have enough to check is\_absolute\_any\_platform, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: no capturable inputs from the test suite; property tier: parameter `p` is annotated `'str | Path | None'` — outside the synthesizable primitive/collection set
· 66 more finding(s) on lines outside this diff (see the check run).
What
is_absolute_any_platformanswers "is this stored path absolute under POSIX or Windows rules" — the right question for a path that travels between machines (asource_fileingraph.json, aprune_sourcesentry, a cache key). It's called on the same few hundred stored paths tens of thousands of times — once or more per node/edge inbuild, and again per resolution pass — and each call built two pathlib objects (aPurePosixPathand aPureWindowsPath) just to read a flag. In one build profile it was 60,675 calls and a large share of the run's pathlib overhead (_parse_path,drive,PurePath.__init__).The change
functools.lru_cache). It's a pure function of the string (and the interpreter's pathlib rules, fixed for the process); nothing touches the filesystem, so there's no staleness to invalidate.PurePosixPath(s).is_absolute()is exactlys.startswith("/"), so that arm is a bare string check, done first — a common in-repo relative path (src/foo.py) returns without constructing any Path, andPureWindowsPathis built only for the drive-letter/UNC forms the cheap check can't settle.Correctness
Semantics are byte-identical to the prior
PurePosixPath(s).is_absolute() or PureWindowsPath(s).is_absolute(). Verified with zero mismatches across 12,379 generated path forms — POSIX roots, drive letters (C:\,C:/,C:rel,c:), UNC (\server\share,//server/share), mixed separators, andNone/empty — plus a fuzz set in the test. This matters because the docstring notes these platform rules are version-sensitive and identity-critical, so the memoization deliberately preserves the exact pathlib calls rather than re-deriving them with a hand-rolled string parser.Measured
Microbenchmark, 10,000 calls over the repeated-path pattern the pipeline actually exhibits (best of 5):
is_absolute_any_platformTests
tests/test_is_absolute_any_platform_memo.py— named edge cases and a fuzz set both matched against the prior implementation; repeated calls hit the cache (1 miss / 99 hits);None/empty short-circuit before the cache; and the POSIX arm equalsstartswith("/"). The full suite matches a freshv8(0.9.63) baseline (zero new failures).🤖 Generated with Claude Code
https://claude.ai/code/session_01JJbLfztSxm2tH5cJwBbe9q