Skip to content

Make CachedArrayReader cache cleanup incremental instead of quadratic - #10901

Draft
zhuqi-lucas wants to merge 1 commit into
apache:mainfrom
zhuqi-lucas:fix-cached-reader-quadratic-cleanup
Draft

Make CachedArrayReader cache cleanup incremental instead of quadratic#10901
zhuqi-lucas wants to merge 1 commit into
apache:mainfrom
zhuqi-lucas:fix-cached-reader-quadratic-cleanup

Conversation

@zhuqi-lucas

@zhuqi-lucas zhuqi-lucas commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

Rationale for this change

cleanup_consumed_batches rescans batch ids from 0 on every consume_batch call, re-removing ids that earlier calls already removed, and takes the shared cache's write lock each time even when there is nothing left to remove:

for batch_id_to_remove in 0..(current_batch_id.val - 1) {
    cache.remove(...);
}

Over a row group with N cached batches this is O(N²) remove calls; the consumer-role reader runs it once per output batch per cached column.

What changes are included in this PR?

Track the already-cleaned frontier (cleaned_up_to) and remove only the new range. When the frontier has not advanced, return without touching the lock.

Are these changes tested?

Covered by the existing cached_array_reader unit tests and the parquet --lib suite (1331 passed; the one failure, test_int96_interop, is a missing parquet-testing file unrelated to this change).

Performance

Two arrow_reader_clickbench bot runs below: neutral. With batch_size = 8192, N is small enough (~15 per row group on this dataset) that the quadratic costs microseconds — so this is a hygiene fix, not a measurable win at this scale. The pattern grows quadratically with row-group size, and dropping the per-call write-lock acquisition also matters more under concurrent readers than in this single-stream bench.

(Per-run flags that did not reproduce: run 1 showed async Q20/Q21 swings that vanished in run 2; async/Q22 shows +11% in both runs, but the same query on the sync and async_object_store variants — same reader code — is neutral-to-faster in both runs, and the async baseline's ±16ms variance points at that variant's flakiness rather than this change.)

Are there any user-facing changes?

No. cleanup_consumed_batches now takes &mut self, but it is a private method of a pub(crate) type.

cleanup_consumed_batches rescanned batch ids from 0 on every consume_batch
call, re-removing ids that earlier calls had already removed, and took the
shared cache's write lock each time even when there was nothing left to do.
Over a row group with N batches this is O(N^2) remove calls on the shared
cache. Track the already-cleaned frontier and only remove the new range,
skipping the lock entirely when the frontier has not advanced.

Found while profiling apache#10774: the consumer-role reader calls
this once per consume_batch, i.e. once per output batch per cached column.
@github-actions github-actions Bot added the parquet Changes to the parquet crate label Aug 28, 2026
@zhuqi-lucas

Copy link
Copy Markdown
Contributor Author

run benchmarks arrow_reader_clickbench

@adriangbot

Copy link
Copy Markdown

🤖 Arrow criterion benchmark running (GKE) | trigger
Instance: c4a-highmem-16 (12 vCPU / 65 GiB) | Linux bench-c5448118799-2031-94b8l 6.12.85+ #1 SMP Sat Jun 27 09:31:30 UTC 2026 aarch64 GNU/Linux

CPU Details (lscpu)
Architecture:                            aarch64
CPU op-mode(s):                          64-bit
Byte Order:                              Little Endian
CPU(s):                                  16
On-line CPU(s) list:                     0-15
Vendor ID:                               ARM
Model name:                              Neoverse-V2
Model:                                   1
Thread(s) per core:                      1
Core(s) per cluster:                     16
Socket(s):                               -
Cluster(s):                              1
Stepping:                                r0p1
BogoMIPS:                                2000.00
Flags:                                   fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 sve asimdfhm dit uscat ilrcpc flagm sb paca pacg dcpodp sve2 sveaes svepmull svebitperm svesha3 svesm4 flagm2 frint svei8mm svebf16 i8mm bf16 dgh rng bti
L1d cache:                               1 MiB (16 instances)
L1i cache:                               1 MiB (16 instances)
L2 cache:                                32 MiB (16 instances)
L3 cache:                                80 MiB (1 instance)
NUMA node(s):                            1
NUMA node0 CPU(s):                       0-15
Vulnerability Gather data sampling:      Not affected
Vulnerability Indirect target selection: Not affected
Vulnerability Itlb multihit:             Not affected
Vulnerability L1tf:                      Not affected
Vulnerability Mds:                       Not affected
Vulnerability Meltdown:                  Not affected
Vulnerability Mmio stale data:           Not affected
Vulnerability Reg file data sampling:    Not affected
Vulnerability Retbleed:                  Not affected
Vulnerability Spec rstack overflow:      Not affected
Vulnerability Spec store bypass:         Mitigation; Speculative Store Bypass disabled via prctl
Vulnerability Spectre v1:                Mitigation; __user pointer sanitization
Vulnerability Spectre v2:                Mitigation; CSV2, BHB
Vulnerability Srbds:                     Not affected
Vulnerability Tsa:                       Not affected
Vulnerability Tsx async abort:           Not affected
Vulnerability Vmscape:                   Not affected

Comparing fix-cached-reader-quadratic-cleanup (e3f0020) to 7e65400 (merge-base) diff

Run configuration
run benchmark arrow_reader_clickbench

BENCH_COMMAND=cargo bench --features=arrow,async,test_common,experimental,object_store --bench arrow_reader_clickbench
Results will be posted here when complete


File an issue against this benchmark runner

@adriangbot

Copy link
Copy Markdown

🤖 Arrow criterion benchmark completed (GKE) | trigger

Instance: c4a-highmem-16 (12 vCPU / 65 GiB)

Comparing fix-cached-reader-quadratic-cleanup (e3f0020) to 7e65400 (merge-base) diff

Run configuration
run benchmark arrow_reader_clickbench
CPU Details (lscpu)
Architecture:                            aarch64
CPU op-mode(s):                          64-bit
Byte Order:                              Little Endian
CPU(s):                                  16
On-line CPU(s) list:                     0-15
Vendor ID:                               ARM
Model name:                              Neoverse-V2
Model:                                   1
Thread(s) per core:                      1
Core(s) per cluster:                     16
Socket(s):                               -
Cluster(s):                              1
Stepping:                                r0p1
BogoMIPS:                                2000.00
Flags:                                   fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 sve asimdfhm dit uscat ilrcpc flagm sb paca pacg dcpodp sve2 sveaes svepmull svebitperm svesha3 svesm4 flagm2 frint svei8mm svebf16 i8mm bf16 dgh rng bti
L1d cache:                               1 MiB (16 instances)
L1i cache:                               1 MiB (16 instances)
L2 cache:                                32 MiB (16 instances)
L3 cache:                                80 MiB (1 instance)
NUMA node(s):                            1
NUMA node0 CPU(s):                       0-15
Vulnerability Gather data sampling:      Not affected
Vulnerability Indirect target selection: Not affected
Vulnerability Itlb multihit:             Not affected
Vulnerability L1tf:                      Not affected
Vulnerability Mds:                       Not affected
Vulnerability Meltdown:                  Not affected
Vulnerability Mmio stale data:           Not affected
Vulnerability Reg file data sampling:    Not affected
Vulnerability Retbleed:                  Not affected
Vulnerability Spec rstack overflow:      Not affected
Vulnerability Spec store bypass:         Mitigation; Speculative Store Bypass disabled via prctl
Vulnerability Spectre v1:                Mitigation; __user pointer sanitization
Vulnerability Spectre v2:                Mitigation; CSV2, BHB
Vulnerability Srbds:                     Not affected
Vulnerability Tsa:                       Not affected
Vulnerability Tsx async abort:           Not affected
Vulnerability Vmscape:                   Not affected
Details

group                                             fix-cached-reader-quadratic-cleanup    main
-----                                             -----------------------------------    ----
arrow_reader_clickbench/async/Q1                  1.01   1091.0±4.61µs        ? ?/sec    1.00   1085.3±6.19µs        ? ?/sec
arrow_reader_clickbench/async/Q10                 1.00      6.2±0.11ms        ? ?/sec    1.02      6.3±0.16ms        ? ?/sec
arrow_reader_clickbench/async/Q11                 1.00      7.1±0.06ms        ? ?/sec    1.05      7.4±0.12ms        ? ?/sec
arrow_reader_clickbench/async/Q12                 1.00     13.3±0.22ms        ? ?/sec    1.01     13.5±0.15ms        ? ?/sec
arrow_reader_clickbench/async/Q13                 1.00     16.0±0.18ms        ? ?/sec    1.01     16.2±0.19ms        ? ?/sec
arrow_reader_clickbench/async/Q14                 1.00     14.8±0.10ms        ? ?/sec    1.01     14.9±0.10ms        ? ?/sec
arrow_reader_clickbench/async/Q19                 1.00      3.1±0.03ms        ? ?/sec    1.00      3.1±0.03ms        ? ?/sec
arrow_reader_clickbench/async/Q20                 1.21    88.9±10.67ms        ? ?/sec    1.00     73.6±0.39ms        ? ?/sec
arrow_reader_clickbench/async/Q21                 1.00     81.9±0.73ms        ? ?/sec    1.17     95.9±0.98ms        ? ?/sec
arrow_reader_clickbench/async/Q22                 1.00    125.0±4.68ms        ? ?/sec    1.13    141.6±1.37ms        ? ?/sec
arrow_reader_clickbench/async/Q23                 1.00    254.0±2.12ms        ? ?/sec    1.01    256.3±4.54ms        ? ?/sec
arrow_reader_clickbench/async/Q24                 1.00     18.5±0.19ms        ? ?/sec    1.01     18.6±0.16ms        ? ?/sec
arrow_reader_clickbench/async/Q27                 1.00     58.4±0.43ms        ? ?/sec    1.00     58.3±0.38ms        ? ?/sec
arrow_reader_clickbench/async/Q28                 1.00     58.3±0.63ms        ? ?/sec    1.00     58.2±0.41ms        ? ?/sec
arrow_reader_clickbench/async/Q30                 1.02     17.8±0.10ms        ? ?/sec    1.00     17.5±0.09ms        ? ?/sec
arrow_reader_clickbench/async/Q36                 1.02     15.3±0.39ms        ? ?/sec    1.00     15.0±0.34ms        ? ?/sec
arrow_reader_clickbench/async/Q37                 1.00      5.0±0.03ms        ? ?/sec    1.00      5.0±0.03ms        ? ?/sec
arrow_reader_clickbench/async/Q38                 1.00     13.5±0.30ms        ? ?/sec    1.01     13.6±0.28ms        ? ?/sec
arrow_reader_clickbench/async/Q39                 1.01     25.2±0.55ms        ? ?/sec    1.00     25.0±0.62ms        ? ?/sec
arrow_reader_clickbench/async/Q40                 1.00      5.3±0.05ms        ? ?/sec    1.01      5.3±0.08ms        ? ?/sec
arrow_reader_clickbench/async/Q41                 1.00      4.6±0.03ms        ? ?/sec    1.00      4.6±0.03ms        ? ?/sec
arrow_reader_clickbench/async/Q42                 1.01      3.4±0.02ms        ? ?/sec    1.00      3.4±0.02ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q1     1.01   1072.8±6.84µs        ? ?/sec    1.00   1063.1±4.10µs        ? ?/sec
arrow_reader_clickbench/async_object_store/Q10    1.01      5.9±0.12ms        ? ?/sec    1.00      5.8±0.04ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q11    1.00      6.8±0.06ms        ? ?/sec    1.00      6.9±0.05ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q12    1.01     13.2±0.07ms        ? ?/sec    1.00     13.1±0.08ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q13    1.00     15.9±0.14ms        ? ?/sec    1.03     16.4±0.21ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q14    1.00     14.7±0.11ms        ? ?/sec    1.03     15.2±0.13ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q19    1.00      3.0±0.02ms        ? ?/sec    1.01      3.0±0.04ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q20    1.00     72.6±0.87ms        ? ?/sec    1.00     72.6±0.63ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q21    1.00     81.3±0.79ms        ? ?/sec    1.00     81.6±0.86ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q22    1.00    100.3±0.76ms        ? ?/sec    1.00    100.3±1.05ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q23    1.00    231.6±0.69ms        ? ?/sec    1.01    233.8±3.40ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q24    1.00     18.0±0.23ms        ? ?/sec    1.01     18.1±0.13ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q27    1.01     57.2±1.82ms        ? ?/sec    1.00     57.0±0.64ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q28    1.00     57.0±0.73ms        ? ?/sec    1.00     57.0±0.80ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q30    1.00     17.2±0.12ms        ? ?/sec    1.00     17.2±0.10ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q36    1.00     14.5±0.21ms        ? ?/sec    1.02     14.8±0.26ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q37    1.00      4.9±0.03ms        ? ?/sec    1.00      4.9±0.04ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q38    1.00     13.2±0.22ms        ? ?/sec    1.01     13.4±0.31ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q39    1.00     24.3±0.53ms        ? ?/sec    1.00     24.3±0.55ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q40    1.03      5.2±0.05ms        ? ?/sec    1.00      5.1±0.03ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q41    1.01      4.5±0.04ms        ? ?/sec    1.00      4.5±0.03ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q42    1.01      3.3±0.02ms        ? ?/sec    1.00      3.2±0.02ms        ? ?/sec
arrow_reader_clickbench/sync/Q1                   1.00    910.3±2.15µs        ? ?/sec    1.01    919.2±2.18µs        ? ?/sec
arrow_reader_clickbench/sync/Q10                  1.00      4.6±0.02ms        ? ?/sec    1.00      4.6±0.01ms        ? ?/sec
arrow_reader_clickbench/sync/Q11                  1.00      5.7±0.05ms        ? ?/sec    1.01      5.7±0.05ms        ? ?/sec
arrow_reader_clickbench/sync/Q12                  1.00     20.5±0.26ms        ? ?/sec    1.01     20.8±0.09ms        ? ?/sec
arrow_reader_clickbench/sync/Q13                  1.00     23.4±0.50ms        ? ?/sec    1.00     23.5±0.13ms        ? ?/sec
arrow_reader_clickbench/sync/Q14                  1.01     22.3±0.14ms        ? ?/sec    1.00     22.2±0.08ms        ? ?/sec
arrow_reader_clickbench/sync/Q19                  1.03      2.8±0.04ms        ? ?/sec    1.00      2.7±0.02ms        ? ?/sec
arrow_reader_clickbench/sync/Q20                  1.02    126.2±0.71ms        ? ?/sec    1.00    124.0±0.24ms        ? ?/sec
arrow_reader_clickbench/sync/Q21                  1.02    100.5±0.70ms        ? ?/sec    1.00     98.2±1.19ms        ? ?/sec
arrow_reader_clickbench/sync/Q22                  1.02    149.5±0.82ms        ? ?/sec    1.00    146.3±0.33ms        ? ?/sec
arrow_reader_clickbench/sync/Q23                  1.00    305.8±8.44ms        ? ?/sec    1.01   307.5±12.99ms        ? ?/sec
arrow_reader_clickbench/sync/Q24                  1.00     26.3±0.13ms        ? ?/sec    1.00     26.2±0.13ms        ? ?/sec
arrow_reader_clickbench/sync/Q27                  1.01    110.2±0.21ms        ? ?/sec    1.00    109.6±0.29ms        ? ?/sec
arrow_reader_clickbench/sync/Q28                  1.01    108.4±0.62ms        ? ?/sec    1.00    107.2±0.28ms        ? ?/sec
arrow_reader_clickbench/sync/Q30                  1.01     17.8±0.15ms        ? ?/sec    1.00     17.6±0.08ms        ? ?/sec
arrow_reader_clickbench/sync/Q36                  1.01     22.3±0.17ms        ? ?/sec    1.00     22.2±0.12ms        ? ?/sec
arrow_reader_clickbench/sync/Q37                  1.01      6.7±0.02ms        ? ?/sec    1.00      6.6±0.04ms        ? ?/sec
arrow_reader_clickbench/sync/Q38                  1.01     11.6±0.09ms        ? ?/sec    1.00     11.5±0.06ms        ? ?/sec
arrow_reader_clickbench/sync/Q39                  1.02     21.2±0.07ms        ? ?/sec    1.00     20.8±0.08ms        ? ?/sec
arrow_reader_clickbench/sync/Q40                  1.02      4.9±0.04ms        ? ?/sec    1.00      4.8±0.03ms        ? ?/sec
arrow_reader_clickbench/sync/Q41                  1.00      5.5±0.04ms        ? ?/sec    1.00      5.5±0.06ms        ? ?/sec
arrow_reader_clickbench/sync/Q42                  1.00      4.4±0.03ms        ? ?/sec    1.00      4.4±0.03ms        ? ?/sec

Resource Usage

base (merge-base)

Metric Value
Wall time 790.2s
Peak memory 286.4 MiB
Avg memory 140.6 MiB
CPU user 698.5s
CPU sys 86.1s
Peak spill 0 B

branch

Metric Value
Wall time 790.2s
Peak memory 286.3 MiB
Avg memory 140.5 MiB
CPU user 700.3s
CPU sys 84.9s
Peak spill 0 B

File an issue against this benchmark runner

@zhuqi-lucas

Copy link
Copy Markdown
Contributor Author

run benchmarks arrow_reader_clickbench

@adriangbot

Copy link
Copy Markdown

🤖 Arrow criterion benchmark running (GKE) | trigger
Instance: c4a-highmem-16 (12 vCPU / 65 GiB) | Linux bench-c5449135497-2032-bgr86 6.12.85+ #1 SMP Sat Jun 27 09:31:30 UTC 2026 aarch64 GNU/Linux

CPU Details (lscpu)
Architecture:                            aarch64
CPU op-mode(s):                          64-bit
Byte Order:                              Little Endian
CPU(s):                                  16
On-line CPU(s) list:                     0-15
Vendor ID:                               ARM
Model name:                              Neoverse-V2
Model:                                   1
Thread(s) per core:                      1
Core(s) per cluster:                     16
Socket(s):                               -
Cluster(s):                              1
Stepping:                                r0p1
BogoMIPS:                                2000.00
Flags:                                   fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 sve asimdfhm dit uscat ilrcpc flagm sb paca pacg dcpodp sve2 sveaes svepmull svebitperm svesha3 svesm4 flagm2 frint svei8mm svebf16 i8mm bf16 dgh rng bti
L1d cache:                               1 MiB (16 instances)
L1i cache:                               1 MiB (16 instances)
L2 cache:                                32 MiB (16 instances)
L3 cache:                                80 MiB (1 instance)
NUMA node(s):                            1
NUMA node0 CPU(s):                       0-15
Vulnerability Gather data sampling:      Not affected
Vulnerability Indirect target selection: Not affected
Vulnerability Itlb multihit:             Not affected
Vulnerability L1tf:                      Not affected
Vulnerability Mds:                       Not affected
Vulnerability Meltdown:                  Not affected
Vulnerability Mmio stale data:           Not affected
Vulnerability Reg file data sampling:    Not affected
Vulnerability Retbleed:                  Not affected
Vulnerability Spec rstack overflow:      Not affected
Vulnerability Spec store bypass:         Mitigation; Speculative Store Bypass disabled via prctl
Vulnerability Spectre v1:                Mitigation; __user pointer sanitization
Vulnerability Spectre v2:                Mitigation; CSV2, BHB
Vulnerability Srbds:                     Not affected
Vulnerability Tsa:                       Not affected
Vulnerability Tsx async abort:           Not affected
Vulnerability Vmscape:                   Not affected

Comparing fix-cached-reader-quadratic-cleanup (e3f0020) to 7e65400 (merge-base) diff

Run configuration
run benchmark arrow_reader_clickbench

BENCH_COMMAND=cargo bench --features=arrow,async,test_common,experimental,object_store --bench arrow_reader_clickbench
Results will be posted here when complete


File an issue against this benchmark runner

@adriangbot

Copy link
Copy Markdown

🤖 Arrow criterion benchmark completed (GKE) | trigger

Instance: c4a-highmem-16 (12 vCPU / 65 GiB)

Comparing fix-cached-reader-quadratic-cleanup (e3f0020) to 7e65400 (merge-base) diff

Run configuration
run benchmark arrow_reader_clickbench
CPU Details (lscpu)
Architecture:                            aarch64
CPU op-mode(s):                          64-bit
Byte Order:                              Little Endian
CPU(s):                                  16
On-line CPU(s) list:                     0-15
Vendor ID:                               ARM
Model name:                              Neoverse-V2
Model:                                   1
Thread(s) per core:                      1
Core(s) per cluster:                     16
Socket(s):                               -
Cluster(s):                              1
Stepping:                                r0p1
BogoMIPS:                                2000.00
Flags:                                   fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 sve asimdfhm dit uscat ilrcpc flagm sb paca pacg dcpodp sve2 sveaes svepmull svebitperm svesha3 svesm4 flagm2 frint svei8mm svebf16 i8mm bf16 dgh rng bti
L1d cache:                               1 MiB (16 instances)
L1i cache:                               1 MiB (16 instances)
L2 cache:                                32 MiB (16 instances)
L3 cache:                                80 MiB (1 instance)
NUMA node(s):                            1
NUMA node0 CPU(s):                       0-15
Vulnerability Gather data sampling:      Not affected
Vulnerability Indirect target selection: Not affected
Vulnerability Itlb multihit:             Not affected
Vulnerability L1tf:                      Not affected
Vulnerability Mds:                       Not affected
Vulnerability Meltdown:                  Not affected
Vulnerability Mmio stale data:           Not affected
Vulnerability Reg file data sampling:    Not affected
Vulnerability Retbleed:                  Not affected
Vulnerability Spec rstack overflow:      Not affected
Vulnerability Spec store bypass:         Mitigation; Speculative Store Bypass disabled via prctl
Vulnerability Spectre v1:                Mitigation; __user pointer sanitization
Vulnerability Spectre v2:                Mitigation; CSV2, BHB
Vulnerability Srbds:                     Not affected
Vulnerability Tsa:                       Not affected
Vulnerability Tsx async abort:           Not affected
Vulnerability Vmscape:                   Not affected
Details

group                                             fix-cached-reader-quadratic-cleanup    main
-----                                             -----------------------------------    ----
arrow_reader_clickbench/async/Q1                  1.00   1086.5±4.73µs        ? ?/sec    1.00   1088.6±5.65µs        ? ?/sec
arrow_reader_clickbench/async/Q10                 1.00      5.9±0.05ms        ? ?/sec    1.00      5.9±0.04ms        ? ?/sec
arrow_reader_clickbench/async/Q11                 1.00      7.0±0.04ms        ? ?/sec    1.00      7.0±0.06ms        ? ?/sec
arrow_reader_clickbench/async/Q12                 1.00     13.2±0.09ms        ? ?/sec    1.00     13.2±0.08ms        ? ?/sec
arrow_reader_clickbench/async/Q13                 1.00     15.9±0.11ms        ? ?/sec    1.01     16.0±0.16ms        ? ?/sec
arrow_reader_clickbench/async/Q14                 1.00     14.7±0.08ms        ? ?/sec    1.00     14.8±0.07ms        ? ?/sec
arrow_reader_clickbench/async/Q19                 1.00      3.1±0.03ms        ? ?/sec    1.01      3.1±0.03ms        ? ?/sec
arrow_reader_clickbench/async/Q20                 1.01     73.8±0.57ms        ? ?/sec    1.00     73.2±0.37ms        ? ?/sec
arrow_reader_clickbench/async/Q21                 1.00     93.0±4.43ms        ? ?/sec    1.02     95.2±0.53ms        ? ?/sec
arrow_reader_clickbench/async/Q22                 1.00   123.8±16.08ms        ? ?/sec    1.11    136.8±6.65ms        ? ?/sec
arrow_reader_clickbench/async/Q23                 1.02    255.1±1.65ms        ? ?/sec    1.00    251.3±1.24ms        ? ?/sec
arrow_reader_clickbench/async/Q24                 1.01     18.3±0.18ms        ? ?/sec    1.00     18.0±0.11ms        ? ?/sec
arrow_reader_clickbench/async/Q27                 1.02     58.3±0.48ms        ? ?/sec    1.00     57.3±0.41ms        ? ?/sec
arrow_reader_clickbench/async/Q28                 1.02     58.2±0.51ms        ? ?/sec    1.00     57.1±0.31ms        ? ?/sec
arrow_reader_clickbench/async/Q30                 1.01     17.7±0.11ms        ? ?/sec    1.00     17.5±0.10ms        ? ?/sec
arrow_reader_clickbench/async/Q36                 1.00     14.7±0.26ms        ? ?/sec    1.02     15.0±0.34ms        ? ?/sec
arrow_reader_clickbench/async/Q37                 1.00      5.0±0.03ms        ? ?/sec    1.00      5.0±0.03ms        ? ?/sec
arrow_reader_clickbench/async/Q38                 1.00     13.6±0.25ms        ? ?/sec    1.00     13.6±0.30ms        ? ?/sec
arrow_reader_clickbench/async/Q39                 1.00     24.7±0.59ms        ? ?/sec    1.00     24.8±0.44ms        ? ?/sec
arrow_reader_clickbench/async/Q40                 1.01      5.3±0.05ms        ? ?/sec    1.00      5.3±0.03ms        ? ?/sec
arrow_reader_clickbench/async/Q41                 1.00      4.7±0.04ms        ? ?/sec    1.00      4.7±0.02ms        ? ?/sec
arrow_reader_clickbench/async/Q42                 1.01      3.4±0.03ms        ? ?/sec    1.00      3.4±0.02ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q1     1.01   1075.1±6.88µs        ? ?/sec    1.00   1064.2±4.91µs        ? ?/sec
arrow_reader_clickbench/async_object_store/Q10    1.00      5.8±0.03ms        ? ?/sec    1.00      5.8±0.03ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q11    1.00      6.9±0.04ms        ? ?/sec    1.00      6.8±0.04ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q12    1.01     13.2±0.12ms        ? ?/sec    1.00     13.1±0.07ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q13    1.00     15.8±0.12ms        ? ?/sec    1.00     15.8±0.11ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q14    1.01     14.8±0.11ms        ? ?/sec    1.00     14.6±0.05ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q19    1.01      3.0±0.03ms        ? ?/sec    1.00      2.9±0.02ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q20    1.01     72.9±0.65ms        ? ?/sec    1.00     71.9±0.54ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q21    1.01     81.7±0.77ms        ? ?/sec    1.00     80.7±0.53ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q22    1.00    100.0±0.81ms        ? ?/sec    1.00     99.5±0.66ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q23    1.01    232.8±0.52ms        ? ?/sec    1.00    230.6±0.79ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q24    1.00     17.9±0.14ms        ? ?/sec    1.00     18.0±0.14ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q27    1.00     56.8±0.59ms        ? ?/sec    1.00     56.7±0.53ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q28    1.01     56.7±0.73ms        ? ?/sec    1.00     56.3±0.44ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q30    1.00     17.2±0.10ms        ? ?/sec    1.00     17.1±0.08ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q36    1.00     14.2±0.24ms        ? ?/sec    1.01     14.4±0.30ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q37    1.00      4.9±0.02ms        ? ?/sec    1.00      4.9±0.04ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q38    1.01     12.9±0.24ms        ? ?/sec    1.00     12.7±0.18ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q39    1.02     23.9±0.60ms        ? ?/sec    1.00     23.5±0.39ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q40    1.00      5.1±0.05ms        ? ?/sec    1.00      5.1±0.04ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q41    1.00      4.5±0.02ms        ? ?/sec    1.00      4.5±0.03ms        ? ?/sec
arrow_reader_clickbench/async_object_store/Q42    1.01      3.3±0.01ms        ? ?/sec    1.00      3.2±0.01ms        ? ?/sec
arrow_reader_clickbench/sync/Q1                   1.00    918.4±3.14µs        ? ?/sec    1.00    915.6±2.26µs        ? ?/sec
arrow_reader_clickbench/sync/Q10                  1.00      4.6±0.02ms        ? ?/sec    1.01      4.6±0.04ms        ? ?/sec
arrow_reader_clickbench/sync/Q11                  1.00      5.6±0.02ms        ? ?/sec    1.01      5.7±0.08ms        ? ?/sec
arrow_reader_clickbench/sync/Q12                  1.00     20.6±0.26ms        ? ?/sec    1.01     20.7±0.09ms        ? ?/sec
arrow_reader_clickbench/sync/Q13                  1.00     23.7±0.49ms        ? ?/sec    1.00     23.6±0.07ms        ? ?/sec
arrow_reader_clickbench/sync/Q14                  1.00     22.0±0.13ms        ? ?/sec    1.00     22.1±0.08ms        ? ?/sec
arrow_reader_clickbench/sync/Q19                  1.01      2.7±0.03ms        ? ?/sec    1.00      2.7±0.02ms        ? ?/sec
arrow_reader_clickbench/sync/Q20                  1.02    125.8±0.31ms        ? ?/sec    1.00    123.3±0.24ms        ? ?/sec
arrow_reader_clickbench/sync/Q21                  1.02     99.8±0.19ms        ? ?/sec    1.00     97.6±1.12ms        ? ?/sec
arrow_reader_clickbench/sync/Q22                  1.02    148.6±0.86ms        ? ?/sec    1.00    145.9±0.37ms        ? ?/sec
arrow_reader_clickbench/sync/Q23                  1.01   306.0±10.44ms        ? ?/sec    1.00   303.1±11.92ms        ? ?/sec
arrow_reader_clickbench/sync/Q24                  1.00     25.5±0.15ms        ? ?/sec    1.01     25.8±0.12ms        ? ?/sec
arrow_reader_clickbench/sync/Q27                  1.01    109.6±0.31ms        ? ?/sec    1.00    108.6±0.22ms        ? ?/sec
arrow_reader_clickbench/sync/Q28                  1.02    107.0±0.31ms        ? ?/sec    1.00    105.4±0.24ms        ? ?/sec
arrow_reader_clickbench/sync/Q30                  1.00     17.4±0.11ms        ? ?/sec    1.00     17.5±0.05ms        ? ?/sec
arrow_reader_clickbench/sync/Q36                  1.00     22.0±0.12ms        ? ?/sec    1.02     22.4±0.08ms        ? ?/sec
arrow_reader_clickbench/sync/Q37                  1.00      6.7±0.02ms        ? ?/sec    1.00      6.7±0.02ms        ? ?/sec
arrow_reader_clickbench/sync/Q38                  1.00     11.5±0.10ms        ? ?/sec    1.00     11.4±0.06ms        ? ?/sec
arrow_reader_clickbench/sync/Q39                  1.01     20.8±0.18ms        ? ?/sec    1.00     20.7±0.13ms        ? ?/sec
arrow_reader_clickbench/sync/Q40                  1.00      4.8±0.03ms        ? ?/sec    1.00      4.8±0.02ms        ? ?/sec
arrow_reader_clickbench/sync/Q41                  1.00      5.4±0.03ms        ? ?/sec    1.00      5.4±0.03ms        ? ?/sec
arrow_reader_clickbench/sync/Q42                  1.00      4.3±0.02ms        ? ?/sec    1.00      4.3±0.03ms        ? ?/sec

Resource Usage

base (merge-base)

Metric Value
Wall time 790.2s
Peak memory 286.5 MiB
Avg memory 141.3 MiB
CPU user 706.0s
CPU sys 80.1s
Peak spill 0 B

branch

Metric Value
Wall time 785.2s
Peak memory 288.4 MiB
Avg memory 136.7 MiB
CPU user 699.6s
CPU sys 81.3s
Peak spill 0 B

File an issue against this benchmark runner

@zhuqi-lucas
zhuqi-lucas marked this pull request as ready for review August 28, 2026 06:58
Copilot AI lite review requested due to automatic review settings August 28, 2026 06:58

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves the performance characteristics of CachedArrayReader’s shared-cache cleanup by making it incremental rather than repeatedly rescanning from batch 0 on every consume_batch call. This reduces unnecessary remove calls and avoids taking the shared cache write lock when there is no new work to do, aligning with the cache’s intended “consume and release” lifecycle during the Consumer phase.

Changes:

  • Add cleaned_up_to to track the already-cleaned batch-id frontier for a Consumer reader.
  • Update cleanup_consumed_batches to remove only newly-consumed batch IDs and to early-return without acquiring the write lock when appropriate.
  • Adjust cleanup_consumed_batches to take &mut self to safely update the cleanup frontier.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@zhuqi-lucas
zhuqi-lucas marked this pull request as draft August 28, 2026 07:12
@alamb

alamb commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Do you think this one ready to review @zhuqi-lucas ?

local_cache: HashMap<BatchID, ArrayRef>,
/// Statistics to report on the Cache behavior
metrics: ArrowReaderMetrics,
/// Exclusive upper bound of the batch ids already removed from the shared

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

},
);
}
drop(cache);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why drop the write lock before setting cleaned_up_to?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

parquet Changes to the parquet crate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants