Skip to content

perf(gfql): resident-index gathers engage for property-seeded lookups (SF1-vs-Neo4j lane)#1770

Merged
lmeyerov merged 1 commit into
masterfrom
perf/gfql-seeded-fastpath-decoupled-index
Jul 22, 2026
Merged

perf(gfql): resident-index gathers engage for property-seeded lookups (SF1-vs-Neo4j lane)#1770
lmeyerov merged 1 commit into
masterfrom
perf/gfql-seeded-fastpath-decoupled-index

Conversation

@lmeyerov

Copy link
Copy Markdown
Contributor

Problem (found via in-harness serve-spies on the SF1 suite, master bffdc34)

The #1768 resident-index acceleration required the seed filter to hit the node BINDING column (node in n0f). The SNB harness — and the general user pattern — binds a synthetic key (__pgbench_node_key__) while MATCH (m {id: $x}) filters the id PROPERTY, so the index path posted 0 serves across the entire SF1 suite: message-creator ran its 39ms scan branch despite valid resident indexes.

Fix

Decouple the gates in all three seeded helpers: the seed row falls back to the property scan when the binding column isn't in the filter, but the CSR adjacency frontier gather and node-id candidate gathers engage whenever valid indexes are resident — their inputs are binding-column values (the index key domain) no matter how the seed rows were found. Decline contract otherwise unchanged (stale/absent index, non-numeric id families).

Verification

  • test_property_seeded_engages_adjacency_index: rebound-key graph (binding ≠ filter column), adjacency-serve asserted + parity vs un-indexed, pandas + polars.
  • Full seeded fast-path suite (65) + index + polars-hop suites (408) green; lint + mypy clean.
  • dgx SF1 harness re-measure: numbers to follow in a comment before review-ready (target: message-creator 38→single-digit ms, flipping the 1.4× Neo4j SF1 loss).

🤖 Generated with Claude Code

https://claude.ai/code/session_01Y6dQEcjdazEnzuvuwf73ZL

The index path required the seed filter on the node BINDING column; the
LDBC/user pattern (synthetic key binding + MATCH on the id property)
never engaged it (found via in-harness serve-spies: 0 serves at SF1).
Decoupled: seed row scans by property when needed; CSR adjacency +
node-id gathers engage regardless — binding-column values are the key
domain however the seed was found. Pinned rebound-key engagement+parity
test (pandas+polars).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y6dQEcjdazEnzuvuwf73ZL
@lmeyerov

Copy link
Copy Markdown
Contributor Author

dgx SF1 re-measure (full cypherbase-polars suite on this branch, same-day-comparable vs out-neo4j-sf1-r4a, all rows harness-validated ok):

query pre-fix this PR Neo4j SF1 verdict
message-creator (IS5) 37.5 7.8 27.7 flips to GFQL 3.6× win (index serves: index_node: 1)
message-content 4.1 4.3 23.0 GFQL 5.3×
seed-lookup (IS1) 106.1 129.2 143.7 GFQL ~1.1× (chain path, unchanged by design — session noise)
one-hop-expand (IS3) 113.1 124.5 180.7 GFQL 1.5×
recent-replies (IC8) 199.3 199.8 104.0 Neo4j 1.9× (chain-traversal gap, documented)

SF1-vs-Neo4j scoreboard: 4 GFQL wins / 1 Neo4j win (was 3/2). No regressions across the other 15 suite rows (all within noise or better). The remaining loss + the two ~100ms wins ride _chain_traversal_polars, which does not route hops through resident indexes — the known #1658/#1676 chain-engagement gap, out of this PR's scope.

🤖 Generated with Claude Code

@lmeyerov

Copy link
Copy Markdown
Contributor Author

X-platform bench-regression validation (dgx RAPIDS container, GPU lanes live): 544 tests pass incl. cuDF + polars-gpu fast-path/index/hop suites; GFQL_PERF_TESTS=1 wall-clock gate passes (indexed ≥1.5× scan @500k edges). Protocol note: this container run is the standing x-platform gate for seeded-fast-path PRs — CI covers py3.8-3.14 × pandas2/3 × polars; the GPU lanes only exist here.

🤖 Generated with Claude Code

@lmeyerov
lmeyerov merged commit 5550b30 into master Jul 22, 2026
69 checks passed
@lmeyerov
lmeyerov deleted the perf/gfql-seeded-fastpath-decoupled-index branch July 22, 2026 03:23
lmeyerov added a commit that referenced this pull request Jul 22, 2026
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y6dQEcjdazEnzuvuwf73ZL
pull Bot pushed a commit to admariner/pygraphistry that referenced this pull request Jul 22, 2026
New docs/source/gfql/indexing.rst: lifecycle guide to GFQL resident
indexes (gfql_index_all / gfql_index_edges / create_index / show_indexes
/ drop_index) — node-id + CSR in/out adjacency sidecars, what engages
them on 0.58.0 (seeded typed-hop fast paths incl. property RETURNs and
property-seeded lookups per graphistry#1768/graphistry#1770, direct g.hop(); general polars
chain traversal honestly noted as not yet covered), the identity +
fingerprint staleness contract with safe declines, engine notes (polars
needs gfql_index_all(engine='polars') until graphistry#1767), 0.58.0-tag measured
numbers, and a runnable end-to-end example (executed).

Wired into the GFQL toctree + recommended paths next to
index_adjacency; CHANGELOG entry under Development > Documentation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y6dQEcjdazEnzuvuwf73ZL
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.

1 participant