Skip to content

Optimize C++ batch decode and output fast paths - #898

Open
ColinLeeo wants to merge 2 commits into
apache:developfrom
ColinLeeo:feature/cpp-decoder-bulk-fast-paths
Open

Optimize C++ batch decode and output fast paths#898
ColinLeeo wants to merge 2 commits into
apache:developfrom
ColinLeeo:feature/cpp-decoder-bulk-fast-paths

Conversation

@ColinLeeo

@ColinLeeo ColinLeeo commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

What changed

This PR adds four local C++ fast paths to the existing batch read pipeline. It does not add a new query mechanism, cache, persistent index, public API, or file-format change.

Area Trigger Fast path Fallback and correctness
Fixed-width TsBlock output All timestamps pass, all values are non-null, source and destination widths match, and no per-value integral filter is required Append the timestamp column and value column once per decoded batch, then update row counts once Null, filtered, promoted, and variable-width data continue through the existing row path
TS2DIFF timestamps An INT64 block has bit_width == 0, meaning all delta residuals are zero Reconstruct the arithmetic progression directly; SIMD builds store four timestamps per iteration Scalar tail handles the final values, non-SIMD builds use the same dedicated scalar path, and the packed stream position is unchanged
Gorilla repeated controls Consecutive values use zero control bits Count and consume a run of zero controls from the 64-bit reservoir and fill the decoded range in bulk The first nonzero control remains unread for normal decoding; truncated input and sentinel handling retain the existing state machine
Gorilla whole-run output A repeated run has been identified Include the current value and repeated suffix in one std::fill_n, with one output-position update Bit-pattern tests cover a non-canonical NaN payload and negative zero; integer output uses the same template path

Why

The optimized batch decoders already produce contiguous timestamp and value arrays, but dense aligned reads copied them into TsBlock vectors one row at a time. Evenly spaced TS2DIFF blocks also fell through to scalar residual reconstruction despite containing no packed residual bytes. Gorilla repeated values still invoked the normal per-value control path even when long zero-control runs were available.

These cases are common in regularly sampled time-series data and can be handled without changing query semantics.

Impact

  • No public API changes.
  • No TsFile format changes.
  • No additional persistent or runtime cache.
  • No PreparedSeries, metadata reuse, or page-position index changes.
  • Existing scalar paths remain the fallback for sparse, filtered, null-containing, type-promoted, and variable-width batches.

Performance

The benchmark harness used query setup, metadata reuse, and page seeking that are deliberately not part of this PR. Absolute latency and throughput are therefore omitted. The table reports only the incremental speedup of each local fast path against the immediately preceding implementation under otherwise identical conditions.

Change Incremental result
Fixed-width batch append about 1.89x throughput
TS2DIFF zero-width path about 1.30x throughput
Gorilla zero-control run about 1.11x throughput
Gorilla whole-run fill, counterbalanced A/B 1.72% lower median latency

These are workload-specific A/B results for the changed code paths, not a general storage throughput guarantee. They should not be multiplied into a cumulative figure because the measurements were collected at separate optimization checkpoints.

Validation

  • Configured and built TsFile_Test with RelWithDebInfo, ENABLE_SIMD=ON, and ENABLE_ANTLR4=OFF.
  • 29 focused fast-path and regression tests passed.
  • 62 related TsBlockTest, EncodingCoverage, GorillaCodecTest, and TsFileReaderTest tests passed; one unrelated large-file test remains disabled upstream.
  • ./mvnw -P with-cpp -DskipTests spotless:check passed.
  • git diff --check passed.

New coverage includes exact-capacity fixed-width appends, dense/null/filtered aligned scans, positive and negative evenly spaced TS2DIFF blocks, long Gorilla runs crossing reservoir and batch boundaries, scalar/batch state transitions, truncated input, embedded NaN handling, non-canonical NaN payloads, and negative zero.

@ColinLeeo
ColinLeeo force-pushed the feature/cpp-decoder-bulk-fast-paths branch from 5622e85 to d0ccf95 Compare August 5, 2026 09:19
@ColinLeeo ColinLeeo changed the title [codex] Optimize C++ batch decode and output fast paths Optimize C++ batch decode and output fast paths Aug 5, 2026
@ColinLeeo
ColinLeeo marked this pull request as ready for review August 5, 2026 11:15
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