Skip to content

perf(paths): memoize is_absolute_any_platform, skip Path construction on the POSIX arm - #3615

Open
abhay-codes07 wants to merge 1 commit into
Graphify-Labs:v8from
abhay-codes07:perf/is-absolute-any-platform-memo
Open

abhay-codes07 wants to merge 1 commit into
Graphify-Labs:v8from
abhay-codes07:perf/is-absolute-any-platform-memo

Conversation

@abhay-codes07

Copy link
Copy Markdown
Contributor

What

is_absolute_any_platform answers "is this stored path absolute under POSIX or Windows rules" — the right question for a path that travels between machines (a source_file in graph.json, a prune_sources entry, a cache key). It's called on the same few hundred stored paths tens of thousands of times — once or more per node/edge in build, and again per resolution pass — and each call built two pathlib objects (a PurePosixPath and a PureWindowsPath) 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

  • Memoize the result (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.
  • POSIX-first shortcut: PurePosixPath(s).is_absolute() is exactly s.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, and PureWindowsPath is 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, and None/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):

before after
is_absolute_any_platform 14.3 ms 0.7 ms (~20×)

Tests

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 equals startswith("/"). The full suite matches a fresh v8 (0.9.63) baseline (zero new failures).

🤖 Generated with Claude Code

https://claude.ai/code/session_01JJbLfztSxm2tH5cJwBbe9q

… 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
Copilot AI lite review requested due to automatic review settings September 16, 2026 18:14

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@graphify-labs graphify-labs Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 — impact
  • tests/test_agents_platform.py — impact
  • tests/test_analyze.py — impact
  • tests/test_atomic_canvas_export.py — impact
  • tests/test_atomic_version_stamp.py — impact
  • tests/test_atomic_writes.py — impact
  • tests/test_benchmark.py — impact
  • tests/test_benchmark_raw_graph.py — impact
  • tests/test_build.py — impact
  • tests/test_build_merge_dedup_scope.py — impact
  • tests/test_build_merge_hyperedges_and_prune.py — impact
  • tests/test_build_merge_shrink_guard.py — impact
  • tests/test_cache.py — impact
  • tests/test_callflow_html.py — impact
  • tests/test_carried_hyperedge_remap.py — impact
  • tests/test_charmap_encoding.py — impact
  • tests/test_chunking.py — impact
  • tests/test_cli_export.py — impact
  • tests/test_cluster.py — impact
  • tests/test_codebuddy.py — impact
  • tests/test_community_labels_skill.py — impact
  • tests/test_confidence.py — impact
  • tests/test_corrupt_graph_json.py — impact
  • tests/test_cpp_objc_cross_file_calls.py — impact
  • tests/test_cross_extension_reexport_self_cycle.py — impact
  • tests/test_dedup.py — impact
  • tests/test_dedup_remaps_hyperedges.py — impact
  • tests/test_definition_file_portability.py — impact
  • tests/test_detect.py — impact
  • tests/test_devin.py — impact
  • tests/test_duplicate_annotation_edges.py — impact
  • tests/test_evidence_binding.py — impact
  • tests/test_explain_cli.py — impact
  • tests/test_export.py — impact
  • tests/test_export_control_characters.py — impact
  • tests/test_export_path_length.py — impact
  • tests/test_external_stub_endpoints.py — impact
  • tests/test_extract.py — impact
  • tests/test_extract_cache_location.py — impact
  • tests/test_extract_cli.py — impact
  • tests/test_falkordb_integration.py — impact
  • tests/test_file_label_disambiguation.py — impact
  • tests/test_global_add_tag_inference.py — impact
  • tests/test_global_graph.py — impact
  • tests/test_go_qualified_resolution.py — impact
  • tests/test_god_nodes_cli.py — impact
  • tests/test_god_nodes_exclude_hubs.py — impact
  • tests/test_hollow_chunks_arm_shrink_guard.py — impact
  • tests/test_hook_out_of_project_paths.py — impact
  • tests/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).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants