perf(gfql): materialize indexed point-query rows directly - #2072
Merged
Conversation
lmeyerov
changed the base branch from
perf/gfql-native-seed-skip-refilter
to
master
September 12, 2026 17:49
lmeyerov
commented
Sep 12, 2026
lmeyerov
commented
Sep 12, 2026
lmeyerov
commented
Sep 12, 2026
lmeyerov
commented
Sep 12, 2026
lmeyerov
commented
Sep 12, 2026
lmeyerov
commented
Sep 12, 2026
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.
Scalar node and directed one-hop queries ending in
rows(...)construct traversal results and evaluate expressions for very small outputs. This change gathers matching rows through resident indexes and projects them directly on pandas, cuDF, and CPU Polars. Joined projections retain one result per matching edge, including repeated matches.The routes preserve row and column order, dtypes, aliases, empty schemas, graph metadata, validation, and unsupported-query fallback. Polars avoids redundant singleton operations, schema inspection, and validation. Supported equality filters on two to 32 eager Polars rows avoid expression plans; CPU Polars gathers of two to eight rows use slices, with scattered gathers limited to 32 columns. Larger and unsupported cases retain the generic path. Valid property indexes can be reused across CPU and GPU execution targets while retaining frame identity and fingerprint checks.
Review hardening includes:
Current published head:
b5703a35c70b3176e4d815adac04bc1bc9252870. Real-fixture phase probes on both preceding revisions identified variable one-row projection costs in Polars expression collection (roughly 0.12–0.32 ms). This repair builds resolved Cypher property columns directly from their Series. General Polars projection also gathers direct columns and short-circuits coalesce when matching dtypes and null counts prove the chosen column; mixed-null, mixed-type, and unsupported expression cases retain the generic path. Existing expression lowering, temporal checks, row cardinality, and source isolation remain in force.The repair adds 64 cases to the existing Polars row-pipeline suite, covering empty/single/larger frames, integer precision, null boundaries, NaN, repeated columns, and categorical/enum/list/struct dtypes. The final focused suite passed 323 tests; broader point/boundary/latency integration passed 697 tests including actual cuDF. Full lint and typing for both changed source files passed. The total review addition is now 641 collected parameterized product cases, not independent bugs or additive execution passes.
Validation on this published revision:
The final latency sentinel passed unchanged absolute and 1.5× historical-baseline drift gates, including correctness, index engagement, and expected fallback. Eight native Polars shapes measured 0.120–0.281 ms against the 0.7 ms limit. IS5 measured 0.192 ms, seeded-hop properties 0.187 ms, and native coalesce 0.165 ms. The alias-collision fallback returned correct results at 23.525 ms. Sampling: eight warmups and 63 measurements.
Broader measurements use product
b5703a35c70b3176e4d815adac04bc1bc9252870and frozen harness557665417a8a5f6f0024b5500e1f9997729d37feon DGX Spark. All 12 current Polars/pandas runs and 18 retained matched competitor runs passed source, dataset, sampling, resource, and result validation. Competitor runs come from the earlier H557 campaign; they were not rerun with this product change. Every shared expected and actual result hash matches. Sampling: eight warmups, 31 measurements, three independent runs; timings include execution and full record materialization. Tables show median-of-run-medians in milliseconds. A dash means not measured. These are internal SNB-derived results, not official LDBC results.SF0.1:
SF1:
Polars leads Kuzu in all ten eligible comparisons. It leads Neo4j on all six point-query comparisons; Neo4j is faster on SF0.1 recent replies. Polars leads Memgraph on message content and creator at both scales; Memgraph is faster on seed lookup at both scales and SF0.1 recent replies. The ±10% ratio band is a reporting convention, not a statistical significance test; SF0.1 recent replies versus Kuzu is close to the boundary. Relative to the original product73565 run medians, message content improved from 0.417→0.171 ms at SF0.1 and 0.762→0.173 ms at SF1; creator improved from 0.513→0.250 ms and 0.708→0.247 ms. Seed lookup increased about 9% at each scale; other measured larger-query changes range from approximately −1% to +7%.
SF0.1 tag cooccurrence is excluded because its selected parameter returns zero rows. SF1 message replies and recent replies were not measured for Polars. Memgraph used a 4 GiB container/3072 MiB engine cap at SF0.1 and a 16 GiB container/12288 MiB engine cap at SF1, consistent across repetitions. The initial failed SF1 import with the smaller engine cap is retained and excluded.
Separate instrumented GPU/index probes passed all seven SF0.1 and four SF1 result checks on the final product revision. GPU collect calls were observed in five SF0.1 queries and two SF1 queries. Message content and creator used eager CPU paths despite the requested GPU target. Seed lookup, message content, and creator all engaged the property index at both scales. A GPU configuration label does not establish GPU execution for every operation. All instrumented timings are excluded from the comparison tables.
Earlier642be latency runs failed relative drift checks. All failures and alternating-pair/phase diagnostics were retained; phase evidence motivated the current direct-projection repair. Current b570 passed the original gates without threshold relaxation. Historical receipts retain their original revision labels.
The harness has correctness/index/route pins and a candidate latency profile requiring all eight native Polars shapes at or below 0.7 ms plus the expected collision fallback. Candidate checks fail on missing or skipped mandatory tests. pyg-bench PR260 adds automatic enforcement when configured. After product merge, actual-master baselines, measured pandas median×1.5 bounds, release configuration activation, and dependent TCK199 validation/merge remain required. They do not use a candidate result relabeled as master.
Colleague-owned aggregation execution/validation and whole-entity metadata work is tracked in issue2074. Integration must preserve both sets of correctness expectations. Docs2017 follows the product and benchmark release gates.
An isolated merge of this head with current master
24233cb701e4757d9d6d71c9c0394ce9d4393351is conflict-free. The combined tree passed 697 focused product tests (one skip; 64 Polars-GPU cases deselected locally) and all 240 TCK199 regressions with pandas, Polars, and cuDF enabled. This is local integration evidence; actual merged-master GPU and baseline validation still follows owner merge.