haohuaijin commented on issue #10926: URL: https://github.com/apache/arrow-rs/issues/10926#issuecomment-5556526592
### Benchmark update: 2–32 predicates, with and without a predicate column cache This compares #10859 at `9263916dc` with its main baseline `7d9bdfd8a`, not with earlier fusion implementations or a moving PR head. Both versions use the async Arrow reader with predicates enabled, batch size 8192, 12 workers, and default cache and row-selection settings. These are direct Arrow benchmarks, not DataFusion SQL benchmarks. Cache eligibility comes from the query projection, without changing cache settings: the predicate column is cached when it is also projected, and is not cached when only a separate payload column is projected. Cache metrics verify both paths. Returned data is consumed and checksummed; no `count(*)` shortcut is used. The 3-million-row matrix covers 1,984 cases: every predicate count from 2 through 32, Int64/String, fragmented/clustered layouts, eight selectivity/order profiles, and both cache paths. Data uses Snappy and dictionary encoding with fallback, following the local ClickBench Parquet files. Selected cases were also tested at 12 million rows. | Predicate column cache | Cases | Geometric-mean latency change vs main | |---|---:|---:| | Not eligible | 992 | -52.12% | | Eligible | 992 | -21.57% | Negative means faster. The overall improvement does not eliminate regressions. The largest repeatable regressions found in the final validation were: | Predicate column cache | Rows | Case | Main | Fusion | Latency change | |---|---:|---|---:|---:|---:| | Not eligible | 12M | Clustered Int64, 8 predicates, approximately 50% survivors per stage | 16.973 ms | 18.514 ms | **+9.08%** | | Eligible | 3M | Clustered Int64, 25 configured predicates, approximately 1% survivors per stage | 1.772 ms | 1.833 ms | **+3.41%** | Both were slower in all eight independent-process rounds. The cache-eligible case still regressed by 2.66% at 12M rows. It terminates after the third predicate eliminates all rows, so this is not a regression from executing all 25 predicates. These maxima are observations from this matrix and selected scale checks, not upper bounds for all workloads. Fusion still trades repeated decoding or predicate-cache replay for survivor materialization and selection composition. It also changes the batch sizes and number of batches seen by later predicates; avoiding repeated decoding alone does not guarantee a speedup. <details> <summary>Dataset, profiles, and validation</summary> - Main matrix: twelve 250K-row files, one row group each. Scale checks: twelve 1M-row files with 450,560 / 450,560 / 98,880-row groups. The local ClickBench reference uses Snappy, dictionary/plain encodings, and 450,560 / 549,440-row groups in its first 1M-row file. This is scaled synthetic data, not a full ClickBench run. - String values contain 32 two-digit fields (64 bytes). Int64 predicates compare seeded hash/modulo-100 values; String predicates compare the corresponding field. This does not cover all SQL operators or string-length distributions. - Fragmented data changes key per row; clustered data repeats each key for 128 rows. This changes both selection locality and compression/dictionary behavior. - Profiles: 99%, 50%, 20%, or 1% expected survivors at every stage; 1% first followed by 99%; 1% last preceded by 99%; alternating 99%/50%; and the same 99% predicate repeated. Rates are approximate; repeated predicates are intentionally correlated. - Screening retained three samples per variant/case. All >2% candidates and the worst case at each count/cache category—139 cases total—were retested, including 51 fresh paired samples per variant. - Some apparent maxima reversed in independent runs. Final validation used fresh processes for each case and each of eight rounds, with three warmups and eight retained samples per variant/round. It covered 29 cases, including every cache-eligible candidate still positive after the 51-pair retest and additional controls. Four selected cases received the same validation at 12M rows. - The final +9.08% result has a paired-round bootstrap 95% interval of [+7.57%, +10.20%]; the +3.41% result has [+0.85%, +5.39%]. Intervals are exploratory and not corrected for multiple comparisons. - A String/cache candidate showed +5.83%, but its interval crossed zero and only four of eight rounds were slower; it is not included as a confirmed regression. - In the 25-predicate cache case, row counts were 3,000,000 → 33,024 → 384 → 0 (12M: 12,000,000 → 126,464 → 896 → 0). - An empty RowGroupCache container may still exist when no column is cache-eligible. Conversely, zero cache hits after filtering to empty does not mean no cache was populated. - Hardware: Apple M2 Max, 12 logical CPUs, 32 GiB RAM; Rust 1.97.1, identical release thin-LTO settings and dependency versions. Scans alternate serially between versions with a warm OS file cache. - No nulls, nested/multi-column predicate projections, or cache-capacity eviction were tested. All output row-count and checksum comparisons passed. </details> -- 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]
