Skip to content

infer_arrow: the columnar boundary — pa.Table in, pa.Table out (TASK-60) - #47

Merged
claude-agent-ahrzb[bot] merged 1 commit into
masterfrom
task-60-arrow-io
Jul 28, 2026
Merged

infer_arrow: the columnar boundary — pa.Table in, pa.Table out (TASK-60)#47
claude-agent-ahrzb[bot] merged 1 commit into
masterfrom
task-60-arrow-io

Conversation

@claude-agent-ahrzb

Copy link
Copy Markdown

Step 1 of the approved columnar roadmap (proposal). An additive fast lane: zero per-value Python objects on either boundary.

How

  • Ingest: walks pyarrow buffers directly (buffer.address/size via the Python buffer API — no arrow-rs dependency): validity + bool bitmaps (LSB), utf8/large_utf8 offsets, non-zero array offsets (slices) honored. Copy-first per the proposal; zero-copy is a measured follow-up.
  • Emit: one pa.Array.from_buffers per OUTPUT column from rust-built buffers (validity bitmap + data / offsets+bytes). Strings emit as large_string.
  • Contract: strict by-name column matching with named rejections (multi-chunk → combine_chunks(), missing column, wrong dtype → cast first, struct models → row path, constant queries). The differential — infer_rows == infer_arrow on every serving scenario, NULLs, and shape='many' LEFT null-extensions — is the test suite: parity by construction.

Measured (p50, release)

scenario n spec_dict infer_arrow python_dict
titanic 1024 3.56 ms 2.57 ms 2.52 ms
house_prices 1024 5.31 ms 2.80 ms 5.03 ms
fraud_txn 1024 7.40 ms 5.06 ms 6.28 ms
store_sales 16384 118 ms 81 ms 90 ms

At n≥1024 the columnar boundary beats the row path everywhere and beats the handcrafted python twin on most scenarios — the first twin wins (house_prices: 1.8× faster). At n=64 pyarrow's fixed API overhead (~150 µs) favors the row path; the columnar-core wave attacks compute next, with the batch-size scaling report.

🤖 Generated with Claude Code

… pa.Table out (TASK-60)

Ingest walks pyarrow buffers directly (address+size via the Python
buffer API, validity/bool bitmaps, utf8 offsets, slice offsets honored —
no arrow-rs dependency) into ColData lanes; emit builds one
pa.Array.from_buffers per OUTPUT COLUMN from rust-built buffers. Zero
per-value Python objects on either side. Strict-by-name column
matching; named rejections for multi-chunk, missing columns, wrong
dtypes, struct models, and the constant path. The differential contract
(infer_rows == infer_arrow, every serving scenario + NULLs + 'many'
LEFT null-extensions) is the test suite.

Measured p50 (release): at n>=1024 infer_arrow beats the row path on
every scenario (house_prices 5308us -> 2795us) and beats the
handcrafted python twin on most (house 0.55x, fraud 0.80x, titanic/
store ~0.9-1.0x) — the first wins over the twin, exactly the boundary
thesis. At n=64 the pyarrow API's fixed ~150us favors the row path
(documented; the columnar-core wave addresses compute next).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@claude-agent-ahrzb
claude-agent-ahrzb Bot merged commit 1d1bb73 into master Jul 28, 2026
1 check passed
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