Skip to content

[Parquet] Populate bloom filters from the dictionary while a column is dictionary encoded - #10966

Open
ranflarion wants to merge 1 commit into
apache:mainfrom
ranflarion:bloom-filter-defer-dictionary-values
Open

[Parquet] Populate bloom filters from the dictionary while a column is dictionary encoded#10966
ranflarion wants to merge 1 commit into
apache:mainfrom
ranflarion:bloom-filter-defer-dictionary-values

Conversation

@ranflarion

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

Rationale for this change

While a column is dictionary encoded every row was still hashed into the bloom filter, although the interner already holds the distinct values. For a low-cardinality column that is N inserts where D carry the same information, and those are exactly the columns that stay dictionary encoded. Suggested by @etseidl in #10963.

What changes are included in this PR?

  • ColumnValueEncoderImpl::write_slice and the byte array encode insert into the filter only when no dictionary encoder is active.
  • flush_dict_page on both encoders inserts every interned value before handing the dictionary page over. It runs on fallback and at chunk close, so after a fallback the filter holds the dictionary's values plus every value written plain afterwards.
  • DictEncoder::uniques exposes the interned values for the primitive path.

The set of values inserted is unchanged and folding decides from the final fill rate, so the serialized filter is byte-identical; only the write-side cost changes.

Benchmark (cargo bench -p parquet --bench arrow_writer -- '<batch>/bloom_filter', Apple M-series, criterion, main vs this branch):

batch main this PR change
string_dictionary_low_cardinality_100 19.20 ms 14.01 ms -27.0%
primitive_non_null 58.90 ms 57.98 ms -1.6%
string_dictionary 48.85 ms 49.10 ms +0.5% (p = 0.24)
string_non_null 108.63 ms 108.96 ms +0.3% (p = 0.05)

Are these changes tested?

Yes. New round-trip tests for StringArray and Int64Array cover a chunk that stays dictionary encoded (asserted through the page encoding mask) and a chunk that falls back to plain after a small dictionary page limit, checking the filter for every written value and for absent ones. The existing bloom filter round-trip tests already sweep dictionary disabled, immediate fallback and dictionary enabled and pass unchanged.

Are there any user-facing changes?

No API or output change. DictEncoder::uniques is new but the type is not exported from the crate.

@github-actions github-actions Bot added the parquet Changes to the parquet crate label Sep 3, 2026
@etseidl

etseidl commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

run benchmark arrow_writer

env:
  BENCH_FILTER: bloom

@adriangbot

Copy link
Copy Markdown

🤖 Arrow criterion benchmark running (GKE) | trigger
Instance: c4a-highmem-16 (12 vCPU / 65 GiB) | Linux bench-c5541809800-2134-kgt5v 6.12.94+ #1 SMP Fri Jul 17 09:42:57 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 bloom-filter-defer-dictionary-values (345ae93) to c134baf (merge-base) diff

Run configuration
run benchmark arrow_writer
env:
  BENCH_FILTER: "bloom"

BENCH_COMMAND=cargo bench --features=arrow,async,test_common,experimental,object_store --bench arrow_writer
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 bloom-filter-defer-dictionary-values (345ae93) to c134baf (merge-base) diff

Run configuration
run benchmark arrow_writer
env:
  BENCH_FILTER: "bloom"
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                                                 bloom-filter-defer-dictionary-values    main
-----                                                 ------------------------------------    ----
bool/bloom_filter                                     1.01     12.8±0.12ms    19.5 MB/sec     1.00     12.7±0.03ms    19.6 MB/sec
bool_non_null/bloom_filter                            1.00      6.6±0.04ms    18.9 MB/sec     1.00      6.6±0.05ms    18.8 MB/sec
bool_ree/bloom_filter                                 1.01     29.6±0.17ms     7.2 MB/sec     1.00     29.3±0.14ms     7.3 MB/sec
decimal/bloom_filter                                  1.00    126.3±2.45ms   475.2 MB/sec     1.03    130.1±2.14ms   461.3 MB/sec
fixed_size_binary_ree/bloom_filter                    1.03     59.9±0.28ms    16.8 MB/sec     1.00     58.4±0.24ms    17.3 MB/sec
float_with_nans/bloom_filter                          1.00     77.9±1.69ms   179.8 MB/sec     1.04     80.8±2.56ms   173.2 MB/sec
fsb/bloom_filter                                      1.04      8.5±0.18ms  1906.8 MB/sec     1.00      8.1±0.04ms  1990.5 MB/sec
int32_ree/bloom_filter                                1.00     35.8±0.48ms    11.4 MB/sec     1.11     39.6±1.11ms    10.3 MB/sec
int32_ree_95pct_null/bloom_filter                     1.00     21.3±0.16ms    19.1 MB/sec     1.03     21.9±0.24ms    18.6 MB/sec
large_string_non_null/bloom_filter                    1.00     54.5±2.16ms     4.6 GB/sec     1.28     69.8±1.29ms     3.6 GB/sec
list_nested/bloom_filter                              1.00    145.5±1.99ms   198.3 MB/sec     1.04    151.6±1.52ms   190.4 MB/sec
list_primitive/bloom_filter                           1.00    276.2±9.93ms  1974.5 MB/sec     1.17   322.7±31.19ms  1690.3 MB/sec
list_primitive_non_null/bloom_filter                  1.00   395.9±35.42ms  1374.8 MB/sec     1.09   432.8±45.93ms  1257.5 MB/sec
list_primitive_sparse_99pct_null/bloom_filter         1.00     12.7±0.04ms     2.9 GB/sec     1.02     13.0±0.41ms     2.8 GB/sec
list_struct_with_list/bloom_filter                    1.00    277.2±3.10ms   164.5 MB/sec     1.06    292.7±6.30ms   155.8 MB/sec
primitive/bloom_filter                                1.00    136.7±0.47ms   328.2 MB/sec     1.12    153.0±5.79ms   293.4 MB/sec
primitive_all_null/bloom_filter                       1.01   905.9±42.62µs    48.4 GB/sec     1.00    895.4±2.07µs    48.9 GB/sec
primitive_non_null/bloom_filter                       1.00     97.1±2.31ms   453.1 MB/sec     1.04    101.0±3.20ms   435.6 MB/sec
primitive_sparse_99pct_null/bloom_filter              1.00     12.2±0.85ms     3.6 GB/sec     1.00     12.3±0.58ms     3.6 GB/sec
short_string_non_null/bloom_filter                    1.00     25.2±0.13ms   475.5 MB/sec     1.18     29.8±0.70ms   402.8 MB/sec
string/bloom_filter                                   1.01   224.0±29.64ms     2.3 GB/sec     1.00   222.2±35.23ms     2.3 GB/sec
string_and_binary_view/bloom_filter                   1.00     65.5±2.40ms   492.4 MB/sec     1.05     68.7±3.69ms   469.7 MB/sec
string_dictionary/bloom_filter                        1.00     83.7±0.40ms     3.1 GB/sec     1.02     85.6±1.08ms     3.0 GB/sec
string_dictionary_low_cardinality_100/bloom_filter    1.00     24.2±0.42ms   165.5 MB/sec     1.36     32.9±0.18ms   121.7 MB/sec
string_dictionary_low_cardinality_20/bloom_filter     1.00     23.8±0.42ms   168.0 MB/sec     1.36     32.3±0.16ms   123.9 MB/sec
string_dictionary_low_cardinality_400/bloom_filter    1.00     25.0±0.47ms   160.5 MB/sec     1.34     33.5±0.21ms   119.9 MB/sec
string_non_null/bloom_filter                          1.03   236.4±25.31ms     2.2 GB/sec     1.00   228.7±17.40ms     2.2 GB/sec
string_ree/bloom_filter                               1.00    125.3±5.00ms   130.9 MB/sec     1.54    193.0±9.08ms    85.0 MB/sec
string_ree_95pct_null/bloom_filter                    1.00     24.5±0.23ms    57.4 MB/sec     1.06     26.1±0.44ms    53.9 MB/sec
struct_all_null/bloom_filter                          1.00    377.7±1.56µs    41.7 GB/sec     1.04    391.1±5.43µs    40.3 GB/sec
struct_non_null/bloom_filter                          1.00     40.6±0.83ms   393.8 MB/sec     1.05     42.7±0.33ms   374.8 MB/sec
struct_sparse_99pct_null/bloom_filter                 1.00      6.6±0.45ms     2.4 GB/sec     1.06      7.0±0.45ms     2.2 GB/sec

Resource Usage

base (merge-base)

Metric Value
Wall time 520.1s
Peak memory 2.8 GiB
Avg memory 2.5 GiB
CPU user 482.2s
CPU sys 32.1s
Peak spill 0 B

branch

Metric Value
Wall time 500.1s
Peak memory 2.8 GiB
Avg memory 2.6 GiB
CPU user 476.0s
CPU sys 18.5s
Peak spill 0 B

File an issue against this benchmark runner

@etseidl

etseidl commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

run benchmark arrow_writer

env:
  BENCH_FILTER: bloom

@adriangbot

Copy link
Copy Markdown

🤖 Arrow criterion benchmark running (GKE) | trigger
Instance: c4a-highmem-16 (12 vCPU / 65 GiB) | Linux bench-c5543084322-2135-dcfg7 6.12.94+ #1 SMP Fri Jul 17 09:42:57 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 bloom-filter-defer-dictionary-values (345ae93) to c134baf (merge-base) diff

Run configuration
run benchmark arrow_writer
env:
  BENCH_FILTER: "bloom"

BENCH_COMMAND=cargo bench --features=arrow,async,test_common,experimental,object_store --bench arrow_writer
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 bloom-filter-defer-dictionary-values (345ae93) to c134baf (merge-base) diff

Run configuration
run benchmark arrow_writer
env:
  BENCH_FILTER: "bloom"
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                                                 bloom-filter-defer-dictionary-values    main
-----                                                 ------------------------------------    ----
bool/bloom_filter                                     1.00     12.8±0.09ms    19.5 MB/sec     1.01     12.9±0.06ms    19.3 MB/sec
bool_non_null/bloom_filter                            1.00      6.6±0.03ms    18.9 MB/sec     1.00      6.6±0.02ms    18.9 MB/sec
bool_ree/bloom_filter                                 1.00     29.3±0.06ms     7.3 MB/sec     1.01     29.6±0.12ms     7.2 MB/sec
decimal/bloom_filter                                  1.08    125.9±1.14ms   476.7 MB/sec     1.00    116.8±1.14ms   513.5 MB/sec
fixed_size_binary_ree/bloom_filter                    1.03     60.7±1.54ms    16.6 MB/sec     1.00     59.2±1.10ms    17.0 MB/sec
float_with_nans/bloom_filter                          1.00     77.5±1.08ms   180.6 MB/sec     1.03     79.5±0.50ms   176.0 MB/sec
fsb/bloom_filter                                      1.03      8.5±0.05ms  1904.5 MB/sec     1.00      8.2±0.08ms  1958.9 MB/sec
int32_ree/bloom_filter                                1.00     35.6±0.09ms    11.4 MB/sec     1.11     39.4±0.34ms    10.3 MB/sec
int32_ree_95pct_null/bloom_filter                     1.00     21.3±0.03ms    19.1 MB/sec     1.01     21.6±0.10ms    18.8 MB/sec
large_string_non_null/bloom_filter                    1.00     51.0±0.07ms     4.9 GB/sec     1.33     68.1±0.09ms     3.7 GB/sec
list_nested/bloom_filter                              1.00    143.0±0.20ms   201.8 MB/sec     1.00    143.2±0.22ms   201.4 MB/sec
list_primitive/bloom_filter                           1.01    280.1±4.21ms  1946.7 MB/sec     1.00    278.3±1.75ms  1959.6 MB/sec
list_primitive_non_null/bloom_filter                  1.01   380.1±10.67ms  1431.7 MB/sec     1.00   376.3±12.03ms  1446.4 MB/sec
list_primitive_sparse_99pct_null/bloom_filter         1.00     13.0±0.12ms     2.8 GB/sec     1.00     12.9±0.10ms     2.8 GB/sec
list_struct_with_list/bloom_filter                    1.00    276.1±0.56ms   165.1 MB/sec     1.00    275.5±0.81ms   165.5 MB/sec
primitive/bloom_filter                                1.00    139.0±0.59ms   322.8 MB/sec     1.03    143.0±0.65ms   313.9 MB/sec
primitive_all_null/bloom_filter                       1.00    892.6±6.63µs    49.1 GB/sec     1.00    888.8±3.68µs    49.3 GB/sec
primitive_non_null/bloom_filter                       1.00     94.2±0.37ms   467.0 MB/sec     1.03     96.9±0.36ms   453.9 MB/sec
primitive_sparse_99pct_null/bloom_filter              1.03     12.6±0.29ms     3.5 GB/sec     1.00     12.2±0.25ms     3.6 GB/sec
short_string_non_null/bloom_filter                    1.00     25.9±0.07ms   464.0 MB/sec     1.09     28.3±0.07ms   424.0 MB/sec
string/bloom_filter                                   1.12   216.8±21.90ms     2.4 GB/sec     1.00   194.3±16.66ms     2.6 GB/sec
string_and_binary_view/bloom_filter                   1.00     63.4±0.27ms   508.8 MB/sec     1.03     65.4±0.22ms   492.8 MB/sec
string_dictionary/bloom_filter                        1.00     85.8±0.67ms     3.0 GB/sec     1.48    126.7±1.26ms     2.0 GB/sec
string_dictionary_low_cardinality_100/bloom_filter    1.00     24.3±0.17ms   165.1 MB/sec     1.35     32.8±0.16ms   122.3 MB/sec
string_dictionary_low_cardinality_20/bloom_filter     1.00     23.9±0.14ms   167.7 MB/sec     1.34     32.1±0.15ms   124.8 MB/sec
string_dictionary_low_cardinality_400/bloom_filter    1.00     24.6±0.16ms   163.0 MB/sec     1.37     33.8±0.23ms   118.6 MB/sec
string_non_null/bloom_filter                          1.02   224.4±10.26ms     2.3 GB/sec     1.00   220.6±15.08ms     2.3 GB/sec
string_ree/bloom_filter                               1.13    148.4±1.30ms   110.6 MB/sec     1.00    130.9±8.38ms   125.3 MB/sec
string_ree_95pct_null/bloom_filter                    1.00     24.8±0.14ms    56.8 MB/sec     1.06     26.2±0.17ms    53.8 MB/sec
struct_all_null/bloom_filter                          1.00    369.0±1.15µs    42.7 GB/sec     1.01    374.2±5.05µs    42.1 GB/sec
struct_non_null/bloom_filter                          1.00     41.3±0.16ms   387.3 MB/sec     1.02     42.2±0.19ms   379.1 MB/sec
struct_sparse_99pct_null/bloom_filter                 1.02      6.6±0.12ms     2.4 GB/sec     1.00      6.5±0.08ms     2.4 GB/sec

Resource Usage

base (merge-base)

Metric Value
Wall time 495.1s
Peak memory 2.8 GiB
Avg memory 2.5 GiB
CPU user 468.9s
CPU sys 20.3s
Peak spill 0 B

branch

Metric Value
Wall time 490.1s
Peak memory 2.9 GiB
Avg memory 2.6 GiB
CPU user 467.5s
CPU sys 20.1s
Peak spill 0 B

File an issue against this benchmark runner

@etseidl

etseidl commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

run benchmark arrow_writer

env:
  BENCH_FILTER: bloom

@adriangbot

Copy link
Copy Markdown

🤖 Arrow criterion benchmark running (GKE) | trigger
Instance: c4a-highmem-16 (12 vCPU / 65 GiB) | Linux bench-c5544856478-2137-s5dv6 6.12.94+ #1 SMP Fri Jul 17 09:42:57 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 bloom-filter-defer-dictionary-values (345ae93) to c134baf (merge-base) diff

Run configuration
run benchmark arrow_writer
env:
  BENCH_FILTER: "bloom"

BENCH_COMMAND=cargo bench --features=arrow,async,test_common,experimental,object_store --bench arrow_writer
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 bloom-filter-defer-dictionary-values (345ae93) to c134baf (merge-base) diff

Run configuration
run benchmark arrow_writer
env:
  BENCH_FILTER: "bloom"
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                                                 bloom-filter-defer-dictionary-values    main
-----                                                 ------------------------------------    ----
bool/bloom_filter                                     1.00     12.8±0.04ms    19.6 MB/sec     1.00     12.8±0.05ms    19.5 MB/sec
bool_non_null/bloom_filter                            1.00      6.6±0.02ms    19.0 MB/sec     1.00      6.6±0.02ms    18.9 MB/sec
bool_ree/bloom_filter                                 1.00     29.4±0.07ms     7.2 MB/sec     1.00     29.4±0.12ms     7.2 MB/sec
decimal/bloom_filter                                  1.00    124.4±0.42ms   482.4 MB/sec     1.17    145.0±0.47ms   413.7 MB/sec
fixed_size_binary_ree/bloom_filter                    1.03     60.3±0.29ms    16.7 MB/sec     1.00     58.5±1.66ms    17.2 MB/sec
float_with_nans/bloom_filter                          1.00     77.4±0.32ms   181.0 MB/sec     1.03     79.7±1.12ms   175.7 MB/sec
fsb/bloom_filter                                      1.02      8.3±0.04ms  1932.1 MB/sec     1.00      8.2±0.05ms  1969.7 MB/sec
int32_ree/bloom_filter                                1.00     35.8±0.19ms    11.4 MB/sec     1.11     39.7±0.31ms    10.3 MB/sec
int32_ree_95pct_null/bloom_filter                     1.00     21.3±0.04ms    19.1 MB/sec     1.01     21.6±0.07ms    18.9 MB/sec
large_string_non_null/bloom_filter                    1.00     50.4±0.15ms     5.0 GB/sec     1.35     67.9±0.50ms     3.7 GB/sec
list_nested/bloom_filter                              1.00    142.4±0.19ms   202.6 MB/sec     1.01    143.5±0.33ms   201.1 MB/sec
list_primitive/bloom_filter                           1.00    274.9±1.39ms  1983.6 MB/sec     1.12   308.5±17.90ms  1767.8 MB/sec
list_primitive_non_null/bloom_filter                  1.00    373.9±4.78ms  1455.5 MB/sec     1.10   410.4±21.40ms  1326.1 MB/sec
list_primitive_sparse_99pct_null/bloom_filter         1.00     12.7±0.08ms     2.9 GB/sec     1.00     12.7±0.07ms     2.9 GB/sec
list_struct_with_list/bloom_filter                    1.00    275.5±0.52ms   165.5 MB/sec     1.02    279.9±1.57ms   162.9 MB/sec
primitive/bloom_filter                                1.00    139.4±0.93ms   321.8 MB/sec     1.03    143.4±0.61ms   312.9 MB/sec
primitive_all_null/bloom_filter                       1.00    878.8±3.08µs    49.9 GB/sec     1.01    888.4±4.16µs    49.3 GB/sec
primitive_non_null/bloom_filter                       1.00     93.7±0.60ms   469.4 MB/sec     1.04     97.9±0.33ms   449.3 MB/sec
primitive_sparse_99pct_null/bloom_filter              1.00     12.1±0.17ms     3.6 GB/sec     1.00     12.1±0.12ms     3.6 GB/sec
short_string_non_null/bloom_filter                    1.00     25.4±0.09ms   473.2 MB/sec     1.13     28.6±0.06ms   419.5 MB/sec
string/bloom_filter                                   1.12   220.0±24.47ms     2.3 GB/sec     1.00   196.2±16.23ms     2.6 GB/sec
string_and_binary_view/bloom_filter                   1.00     62.7±0.20ms   514.1 MB/sec     1.05     65.9±0.24ms   489.3 MB/sec
string_dictionary/bloom_filter                        1.00     85.4±0.72ms     3.0 GB/sec     1.51    128.8±1.38ms     2.0 GB/sec
string_dictionary_low_cardinality_100/bloom_filter    1.00     24.1±0.17ms   166.6 MB/sec     1.38     33.1±0.16ms   120.9 MB/sec
string_dictionary_low_cardinality_20/bloom_filter     1.00     23.9±0.17ms   167.6 MB/sec     1.35     32.1±0.13ms   124.6 MB/sec
string_dictionary_low_cardinality_400/bloom_filter    1.00     24.7±0.20ms   162.3 MB/sec     1.38     34.1±0.17ms   117.6 MB/sec
string_non_null/bloom_filter                          1.00   225.1±11.05ms     2.3 GB/sec     1.05   235.7±19.34ms     2.2 GB/sec
string_ree/bloom_filter                               1.00    151.1±0.99ms   108.6 MB/sec     1.21    183.4±5.44ms    89.5 MB/sec
string_ree_95pct_null/bloom_filter                    1.00     24.8±0.11ms    56.8 MB/sec     1.05     26.0±0.11ms    54.0 MB/sec
struct_all_null/bloom_filter                          1.00    368.4±1.23µs    42.7 GB/sec     1.01    372.9±1.37µs    42.2 GB/sec
struct_non_null/bloom_filter                          1.00     40.7±0.16ms   393.2 MB/sec     1.04     42.5±0.19ms   376.7 MB/sec
struct_sparse_99pct_null/bloom_filter                 1.00      6.4±0.05ms     2.5 GB/sec     1.00      6.4±0.04ms     2.5 GB/sec

Resource Usage

base (merge-base)

Metric Value
Wall time 515.1s
Peak memory 2.8 GiB
Avg memory 2.5 GiB
CPU user 471.0s
CPU sys 39.4s
Peak spill 0 B

branch

Metric Value
Wall time 485.1s
Peak memory 2.8 GiB
Avg memory 2.6 GiB
CPU user 461.2s
CPU sys 21.4s
Peak spill 0 B

File an issue against this benchmark runner

@etseidl

etseidl commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

I've run the benches on my workstation, and the low cardinality dict tests have been consistently better. All others are mixed from run to run, but no consistent regressions.

@etseidl etseidl 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.

The changes look good to me and seem well tested. Thanks @ranflarion.

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.

[Parquet] Populate bloom filters from the dictionary instead of per row while a column is dictionary encoded

3 participants