Skip to content

perf(gfql): native multi-row hop erodes at scale — O(E) edge-frame materialization / #1658 index under-engages on many-seed hops #1756

Description

@lmeyerov

Summary

GFQL native g.hop()/g.chain seeded point lookups are O(degree)-flat and dominate Kuzu at every scale, but native multi-row traversals (many-seed wavefront) grow super-linearly with graph size and lose their lead. Measured same-session, same-box, matched Kuzu, LDBC SF0.1 → SF1 (~11× data), current master 983d2aff, warm-median, gfql_index=use.

Evidence (raw-JSON verified, pandas native-hop backend)

query SF0.1 ms SF1 ms native growth Kuzu growth verdict shift
seed-lookup (point) 0.27 0.30 1.1× (flat) ~1.5× WIN → WIN (widens 4.9→5.9×)
message-creator (point) 0.24 0.26 1.1× (flat) ~1.5× WIN → WIN (5.8×)
message-replies (multi-row) 6.58 57.53 8.7× 23.8→36.0 (1.5×) WIN → LOSE
new-topics (multi-row) 15.8 91.1 5.8× erodes
recent-replies (multi-row) 13.1 89.7 6.8× erodes

Best-engine native-vs-Kuzu tally falls SF0.1 7W/2L → SF1 4W/1T/4L, entirely from multi-row traversal erosion (IS2 WIN→LOSE, IS7 WIN→TIE, IC8 WIN→LOSE). Points and deep-aggregating traversals are unaffected.

Suspected root cause (needs a trace to confirm — do not assume)

The point path hits the #1658 CSR index and is flat. The multi-row path grows ~O(E): candidate causes are (a) the #1658 index not fully engaging when the hop wavefront has many seeds (falls back to a full edge scan), and/or (b) per-call O(E) edge-frame materialization in the harness/executor (the combine_steps/projection family, cf. #1755) that scales with edge count rather than result size.

Why it's fixable (a lever, not a wall)

A prior (uncommitted, never-landed) build with two multi-row opts — memoizing _build_known_pairs and sort/limit-before-projection — recovered the flatness (message-replies stayed a WIN at SF1). So the erosion is addressable; it just isn't on master. This issue tracks landing the real fix + re-measuring.

Ask

  1. Trace the multi-row hop on SF1 (gfql_explain + cProfile) to disentangle index-under-engagement vs O(E) materialization.
  2. Land the multi-row fast path (index engagement on many-seed hops and/or result-sized materialization).
  3. Re-run the native-vs-Kuzu SF0.1→SF1 matrix to confirm multi-row traversals stay flat/winning at scale.

Related: #1755 (single-row seeded abstraction tax, same executor family), #1709 (polars rows-binding NIE). Evidence: plans/gfql-benchmark-numbers/native-vs-competitor-sf{01,1}.md.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions