SteNicholas opened a new issue, #228:
URL: https://github.com/apache/paimon-cpp/issues/228

   ### Search before asking
   
   - [x] I searched in the 
[issues](https://github.com/apache/paimon-cpp/issues) and found nothing similar.
   
   ### Motivation
   
   `benchmark/` currently only contains table-level end-to-end cases 
(`benchmark_case_read.cpp`, `benchmark_case_write.cpp`, 
`benchmark_case_pk_write.cpp`, `benchmark_case_mor_read.cpp`). There is no way 
to measure a change that lives entirely in the format layer — writer 
properties, encoding passthrough, per-batch overhead in the read loop — without 
the noise of catalog lookup, split planning, merge/sort and commit.
   
   That makes format-level optimizations hard to justify and hard to review: a 
proposal either lands without evidence, or it is dropped because nobody can 
quantify it. Several concrete candidates below are currently blocked on exactly 
this.
   
   For reference, the Velox Parquet writer effort 
([facebookincubator/velox#17988](https://github.com/facebookincubator/velox/issues/17988))
 landed a dedicated writer benchmark 
([velox#18052](https://github.com/facebookincubator/velox/pull/18052)) 
alongside the optimizations precisely so each change could be attributed 
individually. The negative result in that same effort — parallel column writing 
plateauing at 1.3–1.6x 
([velox#18128](https://github.com/facebookincubator/velox/pull/18128), closed 
unmerged) — was only identifiable because the measurement infrastructure 
existed.
   
   ### Solution
   
   Add format-level micro-benchmarks for the Parquet reader and writer, driving 
`ParquetFormatWriter` / `ParquetFileBatchReader` directly instead of going 
through the table API.
   
   Suggested coverage:
   
   - **Writer**: flat primitives; low / medium / high cardinality `VARCHAR`; 
`DECIMAL` at precision 9 / 18 / 38; nested `STRUCT` / `LIST` / `VECTOR`; 
multi-batch writes (schema and property setup amortized over N batches); 
compression codecs already supported by `ParquetWriterBuilder`.
   - **Reader**: full scan; projection; page-index filtered reads at varying 
selectivity; skip-heavy reads (many small surviving row ranges); nested column 
reads.
   - **Metrics**: ns/row and bytes written for the writer, ns/row and bytes 
read for the reader, so encoding changes that trade CPU for size are visible.
   
   Candidates to measure once this exists — listed here so they are not lost, 
all currently **unquantified**:
   
   1. **Per-batch fixed cost in `ParquetFileBatchReader::NextBatch`**:
      - `array->Validate()` on every batch 
(`src/paimon/format/parquet/parquet_file_batch_reader.cpp:619`) — structural 
validation that arguably belongs behind a debug-only guard;
      - two `MetricsImpl::SetCounter` calls per batch (`:641`, `:642`), each 
taking a `std::mutex` and doing a `std::map<std::string, uint64_t>` lookup;
      - a fresh `ArrowSchema` export on every batch (`:637`) even though the 
type tree is constant for the whole file.
   
      This is the paimon-cpp analogue of the per-page fixed-overhead work in 
[velox#17989](https://github.com/facebookincubator/velox/pull/17989) (~100 
ns/page). Whether it is worth touching depends entirely on batch size, and 
nothing here should change before there is a number.
   
   2. **Intra-page skip cost in 
`PageFilteredRowGroupReader::ExecuteSkipReadPattern`** 
(`src/paimon/format/parquet/page_filtered_row_group_reader.cpp:243`): the data 
page read plan already skips fully-filtered pages at the IO layer, but inside a 
partially selected page arrow's `TypedColumnReaderImpl::Skip` decodes into a 
scratch buffer and discards (`cpp/src/parquet/column_reader.cc:1249` in arrow 
17). The residual cost scales with the skipped-but-decoded run length and is 
unknown today.
   
   ### Anything else?
   
   This issue came out of evaluating the Velox Parquet reader/writer 
performance issues 
([velox#17994](https://github.com/facebookincubator/velox/issues/17994), 
[velox#17988](https://github.com/facebookincubator/velox/issues/17988)) against 
paimon-cpp. Most of the reader-side items there do not apply, because Velox 
optimizes its own decoders while paimon-cpp reads through arrow 17, which 
already has the equivalents:
   
   - boolean batch decoding — arrow already has bulk paths (`CopyBitmap` for 
the null-free case, `BitBlockCounter` otherwise);
   - `BYTE_STREAM_SPLIT` — arrow 17 supports FLOAT / DOUBLE / INT32 / INT64 / 
FLBA;
   - `FIXED_LEN_BYTE_ARRAY` skip correctness — arrow's skip path is correct;
   - PDEP/PEXT dispatch — arrow already gates BMI2 on 
`CpuInfo::HasEfficientBmi2()`, which excludes AMD entirely.
   
   The items that *do* apply are tracked separately, and both need this 
benchmark to be evaluated properly.
   
   ### Are you willing to submit a PR?
   
   - [x] I'm willing to submit a PR!
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to