Skip to content

perf(arrow-row): avoid encoding oversized dictionary values - #12043

Merged
Rich-T-kid merged 8 commits into
apache:mainfrom
Rich-T-kid:rich-T-kid/row-dictionary-sparse-encode
Nov 5, 2026
Merged

Rich-T-kid merged 8 commits into
apache:mainfrom
Rich-T-kid:rich-T-kid/row-dictionary-sparse-encode

Conversation

@Rich-T-kid

@Rich-T-kid Rich-T-kid commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Why

Closes #11901.

The benchmark coverage for this change is in the consolidated benchmark PR #12054.

RowConverter currently encodes every value in a dictionary before converting a batch. For an 8,192-row slice backed by a large dictionary, the work therefore scales with the retained values array rather than the rows being converted.

DictionaryArray
  keys:     8,192 rows --------+
                               +--> RowConverter --> 8,192 encoded rows
  values: 1,000,000 strings ---+

before: encode all 1,000,000 values --> look up 8,192 keys
after:  gather 8,192 row values      --> encode the row-aligned values

This is a smaller follow-up to #11904. It avoids the hash map and per-row remap used there, and uses the benchmark crossover requested in review to keep small and dense dictionaries on the existing path.

What changed

When a dictionary has at least 32K values and its values array is at least four times longer than the input, gather one value per row and encode that row-aligned array. All other dictionaries keep the existing dictionary-key lookup path.

The benchmark sweep put the crossover between 20K and 24.6K values. The 32K / 4x guard is deliberately conservative.

Results

The hosted exact-ref run is flat at 10K, 1.3x faster at 32K, 3.45x at 100K, and about 33x at 1M. Row decoding is unchanged, and peak memory drops from 56.8 MiB to 29.5 MiB.

Test coverage

One test checks row equality and round-trip decoding for a sliced dictionary with repeated high keys and nulls.

@Rich-T-kid

Copy link
Copy Markdown
Contributor Author

run benchmark row_format

@github-actions github-actions Bot added arrow-row arrow-row crate arrow-core Core crates related to representing arrow data enhancement New feature/addition labels Nov 3, 2026
@adriangbot

Copy link
Copy Markdown

🤖 Benchmark starting (GKE) | trigger

Target: row_format

Sharding factor: 1 (1 workers).

Comparing rich-T-kid/row-dictionary-sparse-encode (65afa03) to b231cf1 (merge-base) diff

Run configuration
run benchmark row_format
shards: 1

Results will be posted when all workers finish.


File an issue against this benchmark runner

@adriangbot

Copy link
Copy Markdown

🤖 Benchmark completed (GKE) | trigger

Target: row_format

Comparing rich-T-kid/row-dictionary-sparse-encode (65afa03) to b231cf1 (merge-base) diff

Run configuration
run benchmark row_format
shards: 1
Details
group                                                                                                                         base                                   changed
-----                                                                                                                         ----                                   -------
append_rows 10 large_list(0) of u64(0)                                                                                        1.01    574.3±2.88ns        ? ?/sec    1.00    568.5±5.59ns        ? ?/sec
append_rows 10 list(0) of u64(0)                                                                                              1.00    587.5±3.85ns        ? ?/sec    1.03    604.3±4.87ns        ? ?/sec
append_rows 4096 4096 string_dictionary(20, 0.5), string_dictionary(30, 0), string_dictionary(100, 0), i64(0)                 1.02    178.0±1.42µs        ? ?/sec    1.00    174.6±1.54µs        ? ?/sec
append_rows 4096 53 columns                                                                                                   1.01    833.4±1.55µs        ? ?/sec    1.00    823.0±2.32µs        ? ?/sec
append_rows 4096 bool(0, 0.5)                                                                                                 1.00      5.1±0.00µs        ? ?/sec    1.00      5.1±0.00µs        ? ?/sec
append_rows 4096 bool(0.3, 0.5)                                                                                               1.00      5.8±0.00µs        ? ?/sec    1.00      5.8±0.00µs        ? ?/sec
append_rows 4096 i64(0)                                                                                                       1.00      4.4±0.00µs        ? ?/sec    1.00      4.4±0.01µs        ? ?/sec
append_rows 4096 i64(0.3)                                                                                                     1.00      5.4±0.01µs        ? ?/sec    1.00      5.4±0.00µs        ? ?/sec
append_rows 4096 large_list(0) of u64(0)                                                                                      1.04     91.4±0.22µs        ? ?/sec    1.00     87.9±0.22µs        ? ?/sec
append_rows 4096 large_list(0) sliced to 10 of u64(0)                                                                         1.00    767.9±3.28ns        ? ?/sec    1.01    774.4±5.06ns        ? ?/sec
append_rows 4096 list(0) of u64(0)                                                                                            1.00     90.0±0.13µs        ? ?/sec    1.04     93.7±0.24µs        ? ?/sec
append_rows 4096 list(0) sliced to 10 of u64(0)                                                                               1.00    848.9±3.21ns        ? ?/sec    1.00    845.2±5.50ns        ? ?/sec
append_rows 4096 run_primitive(1024 physical)                                                                                 1.00     22.3±0.41µs        ? ?/sec    1.01     22.6±0.23µs        ? ?/sec
append_rows 4096 run_primitive(256 physical)                                                                                  1.00     12.3±0.02µs        ? ?/sec    1.00     12.2±0.02µs        ? ?/sec
append_rows 4096 run_primitive(512 physical)                                                                                  1.00     15.6±0.15µs        ? ?/sec    1.00     15.5±0.16µs        ? ?/sec
append_rows 4096 string view(1..100, 0)                                                                                       1.00     41.2±0.15µs        ? ?/sec    1.00     41.1±0.15µs        ? ?/sec
append_rows 4096 string view(1..100, 0.5)                                                                                     1.01     33.5±0.28µs        ? ?/sec    1.00     33.1±0.35µs        ? ?/sec
append_rows 4096 string view(10, 0)                                                                                           1.02     29.5±0.04µs        ? ?/sec    1.00     29.1±0.02µs        ? ?/sec
append_rows 4096 string view(100, 0)                                                                                          1.00     45.3±0.12µs        ? ?/sec    1.00     45.3±0.13µs        ? ?/sec
append_rows 4096 string view(100, 0.5)                                                                                        1.00     49.5±0.21µs        ? ?/sec    1.00     49.4±0.13µs        ? ?/sec
append_rows 4096 string view(30, 0)                                                                                           1.00     34.3±0.06µs        ? ?/sec    1.00     34.3±0.08µs        ? ?/sec
append_rows 4096 string(10, 0)                                                                                                1.00     26.4±0.02µs        ? ?/sec    1.00     26.5±0.02µs        ? ?/sec
append_rows 4096 string(100, 0)                                                                                               1.00     36.4±0.11µs        ? ?/sec    1.00     36.5±0.20µs        ? ?/sec
append_rows 4096 string(100, 0.5)                                                                                             1.06     35.3±0.25µs        ? ?/sec    1.00     33.1±0.41µs        ? ?/sec
append_rows 4096 string(20, 0.5), string(30, 0), string(100, 0), i64(0)                                                       1.01     95.6±1.57µs        ? ?/sec    1.00     95.1±1.57µs        ? ?/sec
append_rows 4096 string(30, 0)                                                                                                1.01     29.7±1.27µs        ? ?/sec    1.00     29.4±1.24µs        ? ?/sec
append_rows 4096 string_dictionary(10, 0)                                                                                     1.00     48.4±0.07µs        ? ?/sec    1.00     48.5±0.12µs        ? ?/sec
append_rows 4096 string_dictionary(100, 0)                                                                                    1.01     72.5±0.14µs        ? ?/sec    1.00     71.8±0.13µs        ? ?/sec
append_rows 4096 string_dictionary(100, 0.5)                                                                                  1.09     54.4±0.19µs        ? ?/sec    1.00     49.8±0.17µs        ? ?/sec
append_rows 4096 string_dictionary(30, 0)                                                                                     1.03     55.8±1.23µs        ? ?/sec    1.00     54.4±1.27µs        ? ?/sec
append_rows 4096 string_dictionary_low_cardinality(10, 0)                                                                     1.00     21.4±0.07µs        ? ?/sec    1.00     21.5±0.09µs        ? ?/sec
append_rows 4096 string_dictionary_low_cardinality(100, 0)                                                                    1.00     31.9±0.04µs        ? ?/sec    1.00     31.8±0.04µs        ? ?/sec
append_rows 4096 string_dictionary_low_cardinality(30, 0)                                                                     1.00     24.0±0.04µs        ? ?/sec    1.02     24.4±0.68µs        ? ?/sec
append_rows 4096 u64(0)                                                                                                       1.00      4.1±0.01µs        ? ?/sec    1.11      4.6±0.56µs        ? ?/sec
append_rows 4096 u64(0.3)                                                                                                     1.02      5.4±0.03µs        ? ?/sec    1.00      5.3±0.00µs        ? ?/sec
append_rows 8192 53 columns                                                                                                   1.01   1725.7±3.91µs        ? ?/sec    1.00   1708.8±7.16µs        ? ?/sec
append_rows 8192 string_dictionary_sparse_keys(10000 values)                                                                                                         1.00    114.8±0.11µs        ? ?/sec
append_rows 8192 string_dictionary_sparse_keys(100000 values)                                                                                                        1.00    201.8±1.38µs        ? ?/sec
append_rows 8192 string_dictionary_sparse_keys(1000000 values)                                                                                                       1.00    201.3±1.36µs        ? ?/sec
append_rows 8192 string_dictionary_sparse_keys(32768 values)                                                                                                         1.00    202.0±2.27µs        ? ?/sec
convert_columns 10 large_list(0) of u64(0)                                                                                    1.02    856.7±3.31ns        ? ?/sec    1.00    840.8±6.15ns        ? ?/sec
convert_columns 10 list(0) of u64(0)                                                                                          1.00    867.1±6.62ns        ? ?/sec    1.01    871.8±6.93ns        ? ?/sec
convert_columns 4096 4096 string_dictionary(20, 0.5), string_dictionary(30, 0), string_dictionary(100, 0), i64(0)             1.02    180.8±1.93µs        ? ?/sec    1.00    178.0±1.48µs        ? ?/sec
convert_columns 4096 53 columns                                                                                               1.01    835.0±1.24µs        ? ?/sec    1.00    825.8±1.49µs        ? ?/sec
convert_columns 4096 bool(0, 0.5)                                                                                             1.00      5.4±0.00µs        ? ?/sec    1.00      5.4±0.00µs        ? ?/sec
convert_columns 4096 bool(0.3, 0.5)                                                                                           1.00      6.0±0.00µs        ? ?/sec    1.00      6.0±0.00µs        ? ?/sec
convert_columns 4096 i64(0)                                                                                                   1.01      4.6±0.03µs        ? ?/sec    1.00      4.6±0.01µs        ? ?/sec
convert_columns 4096 i64(0.3)                                                                                                 1.00      5.6±0.01µs        ? ?/sec    1.01      5.7±0.00µs        ? ?/sec
convert_columns 4096 large_list(0) of u64(0)                                                                                  1.05     92.2±0.25µs        ? ?/sec    1.00     87.9±0.25µs        ? ?/sec
convert_columns 4096 large_list(0) sliced to 10 of u64(0)                                                                     1.03   1060.3±4.48ns        ? ?/sec    1.00   1024.9±6.00ns        ? ?/sec
convert_columns 4096 list(0) of u64(0)                                                                                        1.00     90.7±0.12µs        ? ?/sec    1.04     94.2±0.15µs        ? ?/sec
convert_columns 4096 list(0) sliced to 10 of u64(0)                                                                           1.00   1104.9±4.27ns        ? ?/sec    1.00   1102.1±6.40ns        ? ?/sec
convert_columns 4096 run_primitive(1024 physical)                                                                             1.00     22.8±0.30µs        ? ?/sec    1.00     22.7±0.32µs        ? ?/sec
convert_columns 4096 run_primitive(256 physical)                                                                              1.00     12.6±0.02µs        ? ?/sec    1.00     12.6±0.02µs        ? ?/sec
convert_columns 4096 run_primitive(512 physical)                                                                              1.00     15.9±0.15µs        ? ?/sec    1.00     15.8±0.16µs        ? ?/sec
convert_columns 4096 string view(1..100, 0)                                                                                   1.01     41.4±0.13µs        ? ?/sec    1.00     41.1±0.13µs        ? ?/sec
convert_columns 4096 string view(1..100, 0.5)                                                                                 1.00     33.7±0.34µs        ? ?/sec    1.00     33.6±0.38µs        ? ?/sec
convert_columns 4096 string view(10, 0)                                                                                       1.00     29.6±0.07µs        ? ?/sec    1.00     29.5±0.02µs        ? ?/sec
convert_columns 4096 string view(100, 0)                                                                                      1.01     45.3±0.29µs        ? ?/sec    1.00     44.8±0.32µs        ? ?/sec
convert_columns 4096 string view(100, 0.5)                                                                                    1.00     49.7±0.19µs        ? ?/sec    1.00     49.5±0.18µs        ? ?/sec
convert_columns 4096 string view(30, 0)                                                                                       1.00     34.6±0.05µs        ? ?/sec    1.00     34.7±0.20µs        ? ?/sec
convert_columns 4096 string(10, 0)                                                                                            1.00     26.7±0.03µs        ? ?/sec    1.00     26.6±0.02µs        ? ?/sec
convert_columns 4096 string(100, 0)                                                                                           1.00     36.5±0.13µs        ? ?/sec    1.00     36.5±0.14µs        ? ?/sec
convert_columns 4096 string(100, 0.5)                                                                                         1.07     35.4±0.22µs        ? ?/sec    1.00     33.2±0.34µs        ? ?/sec
convert_columns 4096 string(20, 0.5), string(30, 0), string(100, 0), i64(0)                                                   1.01     95.5±1.47µs        ? ?/sec    1.00     94.6±1.47µs        ? ?/sec
convert_columns 4096 string(30, 0)                                                                                            1.00     29.6±1.25µs        ? ?/sec    1.01     29.7±1.24µs        ? ?/sec
convert_columns 4096 string_dictionary(10, 0)                                                                                 1.00     49.4±0.04µs        ? ?/sec    1.00     49.4±0.06µs        ? ?/sec
convert_columns 4096 string_dictionary(100, 0)                                                                                1.00     74.1±0.15µs        ? ?/sec    1.01     74.5±0.43µs        ? ?/sec
convert_columns 4096 string_dictionary(100, 0.5)                                                                              1.07     55.3±0.16µs        ? ?/sec    1.00     51.5±0.14µs        ? ?/sec
convert_columns 4096 string_dictionary(30, 0)                                                                                 1.00     55.5±1.26µs        ? ?/sec    1.00     55.5±1.38µs        ? ?/sec
convert_columns 4096 string_dictionary_low_cardinality(10, 0)                                                                 1.00     22.4±0.03µs        ? ?/sec    1.01     22.8±0.17µs        ? ?/sec
convert_columns 4096 string_dictionary_low_cardinality(100, 0)                                                                1.00     32.9±0.14µs        ? ?/sec    1.01     33.1±0.19µs        ? ?/sec
convert_columns 4096 string_dictionary_low_cardinality(30, 0)                                                                 1.00     25.1±0.04µs        ? ?/sec    1.01     25.3±0.19µs        ? ?/sec
convert_columns 4096 u64(0)                                                                                                   1.02      4.5±0.17µs        ? ?/sec    1.00      4.4±0.02µs        ? ?/sec
convert_columns 4096 u64(0.3)                                                                                                 1.01      5.6±0.03µs        ? ?/sec    1.00      5.5±0.01µs        ? ?/sec
convert_columns 8192 53 columns                                                                                               1.01   1730.7±3.80µs        ? ?/sec    1.00   1712.2±4.32µs        ? ?/sec
convert_columns 8192 string_dictionary_sparse_keys(10000 values)                                                                                                     1.00    115.6±0.11µs        ? ?/sec
convert_columns 8192 string_dictionary_sparse_keys(100000 values)                                                                                                    1.00    202.4±1.50µs        ? ?/sec
convert_columns 8192 string_dictionary_sparse_keys(1000000 values)                                                                                                   1.00    205.1±3.07µs        ? ?/sec
convert_columns 8192 string_dictionary_sparse_keys(32768 values)                                                                                                     1.00    202.2±1.20µs        ? ?/sec
convert_columns_prepared 10 large_list(0) of u64(0)                                                                           1.01    640.1±2.61ns        ? ?/sec    1.00    634.3±6.94ns        ? ?/sec
convert_columns_prepared 10 list(0) of u64(0)                                                                                 1.00    652.6±2.51ns        ? ?/sec    1.02    664.8±5.91ns        ? ?/sec
convert_columns_prepared 4096 4096 string_dictionary(20, 0.5), string_dictionary(30, 0), string_dictionary(100, 0), i64(0)    1.02    178.1±1.99µs        ? ?/sec    1.00    175.4±1.43µs        ? ?/sec
convert_columns_prepared 4096 53 columns                                                                                      1.01    833.3±1.48µs        ? ?/sec    1.00    825.1±1.17µs        ? ?/sec
convert_columns_prepared 4096 bool(0, 0.5)                                                                                    1.00      5.3±0.00µs        ? ?/sec    1.00      5.3±0.00µs        ? ?/sec
convert_columns_prepared 4096 bool(0.3, 0.5)                                                                                  1.00      5.9±0.00µs        ? ?/sec    1.00      5.9±0.00µs        ? ?/sec
convert_columns_prepared 4096 i64(0)                                                                                          1.00      4.4±0.01µs        ? ?/sec    1.00      4.5±0.00µs        ? ?/sec
convert_columns_prepared 4096 i64(0.3)                                                                                        1.00      5.5±0.00µs        ? ?/sec    1.01      5.5±0.00µs        ? ?/sec
convert_columns_prepared 4096 large_list(0) of u64(0)                                                                         1.05     91.8±0.27µs        ? ?/sec    1.00     87.7±0.20µs        ? ?/sec
convert_columns_prepared 4096 large_list(0) sliced to 10 of u64(0)                                                            1.02    854.3±3.62ns        ? ?/sec    1.00    841.0±5.88ns        ? ?/sec
convert_columns_prepared 4096 list(0) of u64(0)                                                                               1.00     90.1±0.12µs        ? ?/sec    1.04     93.7±0.20µs        ? ?/sec
convert_columns_prepared 4096 list(0) sliced to 10 of u64(0)                                                                  1.00    907.5±2.73ns        ? ?/sec    1.00    911.3±6.46ns        ? ?/sec
convert_columns_prepared 4096 run_primitive(1024 physical)                                                                    1.01     22.8±0.22µs        ? ?/sec    1.00     22.5±0.32µs        ? ?/sec
convert_columns_prepared 4096 run_primitive(256 physical)                                                                     1.00     12.4±0.02µs        ? ?/sec    1.00     12.3±0.04µs        ? ?/sec
convert_columns_prepared 4096 run_primitive(512 physical)                                                                     1.00     15.6±0.14µs        ? ?/sec    1.00     15.6±0.17µs        ? ?/sec
convert_columns_prepared 4096 string view(1..100, 0)                                                                          1.00     41.4±0.10µs        ? ?/sec    1.00     41.2±0.13µs        ? ?/sec
convert_columns_prepared 4096 string view(1..100, 0.5)                                                                        1.02     34.0±0.32µs        ? ?/sec    1.00     33.4±0.32µs        ? ?/sec
convert_columns_prepared 4096 string view(10, 0)                                                                              1.00     29.4±0.03µs        ? ?/sec    1.00     29.2±0.02µs        ? ?/sec
convert_columns_prepared 4096 string view(100, 0)                                                                             1.01     45.3±0.14µs        ? ?/sec    1.00     45.0±0.12µs        ? ?/sec
convert_columns_prepared 4096 string view(100, 0.5)                                                                           1.00     49.6±0.16µs        ? ?/sec    1.00     49.5±0.15µs        ? ?/sec
convert_columns_prepared 4096 string view(30, 0)                                                                              1.00     34.5±0.04µs        ? ?/sec    1.00     34.5±0.09µs        ? ?/sec
convert_columns_prepared 4096 string(10, 0)                                                                                   1.00     26.5±0.03µs        ? ?/sec    1.00     26.5±0.02µs        ? ?/sec
convert_columns_prepared 4096 string(100, 0)                                                                                  1.00     36.5±0.12µs        ? ?/sec    1.00     36.5±0.17µs        ? ?/sec
convert_columns_prepared 4096 string(100, 0.5)                                                                                1.05     35.3±0.26µs        ? ?/sec    1.00     33.8±0.46µs        ? ?/sec
convert_columns_prepared 4096 string(20, 0.5), string(30, 0), string(100, 0), i64(0)                                          1.01     95.5±1.52µs        ? ?/sec    1.00     94.7±1.53µs        ? ?/sec
convert_columns_prepared 4096 string(30, 0)                                                                                   1.00     29.5±1.25µs        ? ?/sec    1.00     29.5±1.26µs        ? ?/sec
convert_columns_prepared 4096 string_dictionary(10, 0)                                                                        1.00     48.4±0.04µs        ? ?/sec    1.00     48.3±0.04µs        ? ?/sec
convert_columns_prepared 4096 string_dictionary(100, 0)                                                                       1.01     72.9±0.86µs        ? ?/sec    1.00     71.9±0.21µs        ? ?/sec
convert_columns_prepared 4096 string_dictionary(100, 0.5)                                                                     1.08     54.4±0.20µs        ? ?/sec    1.00     50.3±0.25µs        ? ?/sec
convert_columns_prepared 4096 string_dictionary(30, 0)                                                                        1.03     56.0±1.40µs        ? ?/sec    1.00     54.3±1.31µs        ? ?/sec
convert_columns_prepared 4096 string_dictionary_low_cardinality(10, 0)                                                        1.00     21.5±0.03µs        ? ?/sec    1.00     21.4±0.04µs        ? ?/sec
convert_columns_prepared 4096 string_dictionary_low_cardinality(100, 0)                                                       1.00     32.0±0.02µs        ? ?/sec    1.00     31.9±0.04µs        ? ?/sec
convert_columns_prepared 4096 string_dictionary_low_cardinality(30, 0)                                                        1.02     24.5±0.42µs        ? ?/sec    1.00     24.0±0.03µs        ? ?/sec
convert_columns_prepared 4096 u64(0)                                                                                          1.00      4.3±0.02µs        ? ?/sec    1.00      4.3±0.01µs        ? ?/sec
convert_columns_prepared 4096 u64(0.3)                                                                                        1.02      5.5±0.04µs        ? ?/sec    1.00      5.4±0.00µs        ? ?/sec
convert_columns_prepared 8192 53 columns                                                                                      1.01   1729.8±3.25µs        ? ?/sec    1.00   1710.0±9.57µs        ? ?/sec
convert_columns_prepared 8192 string_dictionary_sparse_keys(10000 values)                                                                                            1.00    114.5±0.14µs        ? ?/sec
convert_columns_prepared 8192 string_dictionary_sparse_keys(100000 values)                                                                                           1.00    201.6±1.03µs        ? ?/sec
convert_columns_prepared 8192 string_dictionary_sparse_keys(1000000 values)                                                                                          1.00    200.8±1.10µs        ? ?/sec
convert_columns_prepared 8192 string_dictionary_sparse_keys(32768 values)                                                                                            1.00    201.0±1.40µs        ? ?/sec
convert_rows 10 large_list(0) of u64(0)                                                                                       1.01    910.7±4.38ns        ? ?/sec    1.00    904.0±3.92ns        ? ?/sec
convert_rows 10 list(0) of u64(0)                                                                                             1.00    959.8±4.20ns        ? ?/sec    1.00    955.5±5.33ns        ? ?/sec
convert_rows 4096 4096 string_dictionary(20, 0.5), string_dictionary(30, 0), string_dictionary(100, 0), i64(0)                1.00    174.6±0.51µs        ? ?/sec    1.03    180.4±0.57µs        ? ?/sec
convert_rows 4096 53 columns                                                                                                  1.03   1764.2±2.09µs        ? ?/sec    1.00   1710.4±3.59µs        ? ?/sec
convert_rows 4096 bool(0, 0.5)                                                                                                1.01     13.5±0.02µs        ? ?/sec    1.00     13.4±0.03µs        ? ?/sec
convert_rows 4096 bool(0.3, 0.5)                                                                                              1.01     13.5±0.03µs        ? ?/sec    1.00     13.4±0.03µs        ? ?/sec
convert_rows 4096 i64(0)                                                                                                      1.00     25.8±0.02µs        ? ?/sec    1.01     26.0±0.02µs        ? ?/sec
convert_rows 4096 i64(0.3)                                                                                                    1.00     25.8±0.04µs        ? ?/sec    1.01     26.1±0.03µs        ? ?/sec
convert_rows 4096 large_list(0) of u64(0)                                                                                     1.00    169.2±0.35µs        ? ?/sec    1.00    169.7±0.40µs        ? ?/sec
convert_rows 4096 large_list(0) sliced to 10 of u64(0)                                                                        1.01   1209.3±3.66ns        ? ?/sec    1.00   1200.0±4.86ns        ? ?/sec
convert_rows 4096 list(0) of u64(0)                                                                                           1.00    168.5±0.27µs        ? ?/sec    1.01    170.1±0.30µs        ? ?/sec
convert_rows 4096 list(0) sliced to 10 of u64(0)                                                                              1.00   1318.9±5.68ns        ? ?/sec    1.01   1329.9±4.59ns        ? ?/sec
convert_rows 4096 run_primitive(1024 physical)                                                                                1.00     75.8±0.08µs        ? ?/sec    1.01     76.6±0.19µs        ? ?/sec
convert_rows 4096 run_primitive(256 physical)                                                                                 1.00     53.8±0.06µs        ? ?/sec    1.00     54.0±0.09µs        ? ?/sec
convert_rows 4096 run_primitive(512 physical)                                                                                 1.00     61.5±0.07µs        ? ?/sec    1.01     62.0±0.13µs        ? ?/sec
convert_rows 4096 string view(1..100, 0)                                                                                      1.00     56.1±0.08µs        ? ?/sec    1.35     75.8±0.38µs        ? ?/sec
convert_rows 4096 string view(1..100, 0.5)                                                                                    1.00     37.8±0.06µs        ? ?/sec    1.77     67.0±0.46µs        ? ?/sec
convert_rows 4096 string view(10, 0)                                                                                          1.02     43.6±0.34µs        ? ?/sec    1.00     42.8±0.08µs        ? ?/sec
convert_rows 4096 string view(100, 0)                                                                                         1.00     70.7±0.11µs        ? ?/sec    1.02     72.1±0.09µs        ? ?/sec
convert_rows 4096 string view(100, 0.5)                                                                                       1.00     48.9±0.11µs        ? ?/sec    1.14     55.9±0.21µs        ? ?/sec
convert_rows 4096 string view(30, 0)                                                                                          1.00     49.8±0.02µs        ? ?/sec    1.00     50.0±0.03µs        ? ?/sec
convert_rows 4096 string(10, 0)                                                                                               1.03     36.7±0.04µs        ? ?/sec    1.00     35.5±0.05µs        ? ?/sec
convert_rows 4096 string(100, 0)                                                                                              1.00     62.5±0.07µs        ? ?/sec    1.00     62.4±0.10µs        ? ?/sec
convert_rows 4096 string(100, 0.5)                                                                                            1.13     49.8±0.28µs        ? ?/sec    1.00     44.0±0.07µs        ? ?/sec
convert_rows 4096 string(20, 0.5), string(30, 0), string(100, 0), i64(0)                                                      1.03    176.0±0.49µs        ? ?/sec    1.00    171.2±0.39µs        ? ?/sec
convert_rows 4096 string(30, 0)                                                                                               1.00     43.8±0.04µs        ? ?/sec    1.00     43.8±0.06µs        ? ?/sec
convert_rows 4096 string_dictionary(10, 0)                                                                                    1.00     35.6±0.04µs        ? ?/sec    1.00     35.6±0.02µs        ? ?/sec
convert_rows 4096 string_dictionary(100, 0)                                                                                   1.01     64.0±0.14µs        ? ?/sec    1.00     63.4±0.33µs        ? ?/sec
convert_rows 4096 string_dictionary(100, 0.5)                                                                                 1.13     49.8±0.15µs        ? ?/sec    1.00     44.1±0.10µs        ? ?/sec
convert_rows 4096 string_dictionary(30, 0)                                                                                    1.03     45.0±0.38µs        ? ?/sec    1.00     43.8±0.04µs        ? ?/sec
convert_rows 4096 string_dictionary_low_cardinality(10, 0)                                                                    1.00     35.7±0.03µs        ? ?/sec    1.00     35.8±0.04µs        ? ?/sec
convert_rows 4096 string_dictionary_low_cardinality(100, 0)                                                                   1.00     63.3±0.10µs        ? ?/sec    1.00     63.2±0.27µs        ? ?/sec
convert_rows 4096 string_dictionary_low_cardinality(30, 0)                                                                    1.00     43.9±0.03µs        ? ?/sec    1.02     44.8±0.40µs        ? ?/sec
convert_rows 4096 u64(0)                                                                                                      1.00     25.6±0.03µs        ? ?/sec    1.01     25.8±0.03µs        ? ?/sec
convert_rows 4096 u64(0.3)                                                                                                    1.00     25.6±0.02µs        ? ?/sec    1.01     25.8±0.03µs        ? ?/sec
convert_rows 8192 53 columns                                                                                                  1.05      4.3±0.01ms        ? ?/sec    1.00      4.1±0.01ms        ? ?/sec
convert_rows 8192 string_dictionary_sparse_keys(10000 values)                                                                                                        1.00     70.9±0.09µs        ? ?/sec
convert_rows 8192 string_dictionary_sparse_keys(100000 values)                                                                                                       1.00     73.4±0.08µs        ? ?/sec
convert_rows 8192 string_dictionary_sparse_keys(1000000 values)                                                                                                      1.00     73.4±0.15µs        ? ?/sec
convert_rows 8192 string_dictionary_sparse_keys(32768 values)                                                                                                        1.00     71.5±0.23µs        ? ?/sec
convert_rows_parsed 4096 string view(1..100, 0)                                                                               1.00     55.6±0.20µs        ? ?/sec    1.32     73.5±0.35µs        ? ?/sec
convert_rows_parsed 4096 string view(1..100, 0.5)                                                                             1.00     35.8±0.06µs        ? ?/sec    1.80     64.4±0.51µs        ? ?/sec
convert_rows_parsed 4096 string view(10, 0)                                                                                   1.00     43.8±0.18µs        ? ?/sec    1.02     44.6±0.03µs        ? ?/sec
convert_rows_parsed 4096 string view(100, 0)                                                                                  1.04     77.9±0.10µs        ? ?/sec    1.00     74.7±0.06µs        ? ?/sec
convert_rows_parsed 4096 string view(100, 0.5)                                                                                1.00     49.4±0.28µs        ? ?/sec    1.14     56.2±0.47µs        ? ?/sec
convert_rows_parsed 4096 string view(30, 0)                                                                                   1.00     45.7±0.03µs        ? ?/sec    1.00     45.6±0.02µs        ? ?/sec
convert_rows_parsed 4096 string(10, 0)                                                                                        1.04     36.6±0.37µs        ? ?/sec    1.00     35.3±1.16µs        ? ?/sec
convert_rows_parsed 4096 string(100, 0)                                                                                       1.00     77.7±0.42µs        ? ?/sec    1.06     82.1±0.63µs        ? ?/sec
convert_rows_parsed 4096 string(100, 0.5)                                                                                     1.12     55.1±0.16µs        ? ?/sec    1.00     49.4±0.17µs        ? ?/sec
convert_rows_parsed 4096 string(30, 0)                                                                                        1.00     44.6±0.05µs        ? ?/sec    1.00     44.6±0.05µs        ? ?/sec
iterate rows                                                                                                                  1.00      2.0±0.00µs        ? ?/sec    2.13      4.3±5.08µs        ? ?/sec

Per-runner information
row_format — shard 1/1

Node: gk3-benchmark-cluster-nap-r5b1bsxo-0e1bca2a-8d8c

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

uname:

Linux bench-c6595411004-4302-q7vzf 6.12.105+ #1 SMP Sat Sep 19 07:55:25 UTC 2026 aarch64 GNU/Linux

BENCH_COMMAND:

cargo bench --features=arrow,async,test_common,experimental,object_store --bench row_format
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
Resource Usage

base (merge-base)

Metric Value
Wall time 1530.3s
Peak memory 24.8 MiB
Avg memory 16.8 MiB
CPU user 1526.5s
CPU sys 0.1s
Peak spill 0 B

branch

Metric Value
Wall time 1690.4s
Peak memory 30.2 MiB
Avg memory 17.3 MiB
CPU user 1686.0s
CPU sys 0.1s
Peak spill 0 B

File an issue against this benchmark runner

Add an 8,192-row cardinality sweep so sparse dictionary encoding can be compared at the measured crossover and at larger retained value counts.
RowConverter currently encodes every dictionary value, even when a batch references only a small subset. Gather one value per row for dictionaries with at least 32K values and four times more values than rows, avoiding the large values-array cost without penalizing ordinary dictionaries.

The cutoff is based on an 8,192-row cardinality sweep: the gathered path crosses over between 20K and 24.6K values, so 32K is deliberately conservative.
@Rich-T-kid
Rich-T-kid force-pushed the rich-T-kid/row-dictionary-sparse-encode branch from 65afa03 to 1252049 Compare November 3, 2026 14:02
@Rich-T-kid

Copy link
Copy Markdown
Contributor Author

run benchmark row_format
env:
BENCH_FILTER: string_dictionary_sparse_keys
baseline:
ref: "1cb7eaaf56ada718e4ca2774c054561974f5ec53"
changed:
ref: "1252049ea59fe98a10fd1498c2da14fb10dace48"

@adriangbot

Copy link
Copy Markdown

🤖 Benchmark starting (GKE) | trigger

Target: row_format

Sharding factor: 1 (1 workers).

Comparing 1252049 (1252049) to 1cb7eaa diff

Run configuration
run benchmark row_format
baseline:
  ref: 1cb7eaaf56ada718e4ca2774c054561974f5ec53
changed:
  ref: 1252049ea59fe98a10fd1498c2da14fb10dace48
env:
  BENCH_FILTER: string_dictionary_sparse_keys
shards: 1

Results will be posted when all workers finish.


File an issue against this benchmark runner

@adriangbot

Copy link
Copy Markdown

🤖 Benchmark completed (GKE) | trigger

Target: row_format

Comparing 1252049 (1252049) to 1cb7eaa diff

Run configuration
run benchmark row_format
baseline:
  ref: 1cb7eaaf56ada718e4ca2774c054561974f5ec53
changed:
  ref: 1252049ea59fe98a10fd1498c2da14fb10dace48
env:
  BENCH_FILTER: string_dictionary_sparse_keys
shards: 1
Details
group                                                                          base                                   changed
-----                                                                          ----                                   -------
append_rows 8192 string_dictionary_sparse_keys(10000 values)                   1.00    114.4±0.14µs        ? ?/sec    1.03    117.5±0.39µs        ? ?/sec
append_rows 8192 string_dictionary_sparse_keys(100000 values)                  3.45    699.1±1.04µs        ? ?/sec    1.00    202.7±1.60µs        ? ?/sec
append_rows 8192 string_dictionary_sparse_keys(1000000 values)                 32.66     6.7±0.04ms        ? ?/sec    1.00    205.6±1.41µs        ? ?/sec
append_rows 8192 string_dictionary_sparse_keys(32768 values)                   1.30    262.1±0.37µs        ? ?/sec    1.00    201.7±1.14µs        ? ?/sec
convert_columns 8192 string_dictionary_sparse_keys(10000 values)               1.00    115.6±0.19µs        ? ?/sec    1.00    115.8±0.53µs        ? ?/sec
convert_columns 8192 string_dictionary_sparse_keys(100000 values)              3.46    703.8±1.38µs        ? ?/sec    1.00    203.3±1.69µs        ? ?/sec
convert_columns 8192 string_dictionary_sparse_keys(1000000 values)             32.65     6.7±0.03ms        ? ?/sec    1.00    205.1±2.03µs        ? ?/sec
convert_columns 8192 string_dictionary_sparse_keys(32768 values)               1.29    264.0±0.41µs        ? ?/sec    1.00    204.6±1.59µs        ? ?/sec
convert_columns_prepared 8192 string_dictionary_sparse_keys(10000 values)      1.00    114.9±0.36µs        ? ?/sec    1.00    114.4±0.14µs        ? ?/sec
convert_columns_prepared 8192 string_dictionary_sparse_keys(100000 values)     3.45    699.6±1.80µs        ? ?/sec    1.00    203.0±2.61µs        ? ?/sec
convert_columns_prepared 8192 string_dictionary_sparse_keys(1000000 values)    33.45     6.7±0.05ms        ? ?/sec    1.00    201.1±1.25µs        ? ?/sec
convert_columns_prepared 8192 string_dictionary_sparse_keys(32768 values)      1.30    262.1±0.29µs        ? ?/sec    1.00    200.9±1.11µs        ? ?/sec
convert_rows 8192 string_dictionary_sparse_keys(10000 values)                  1.00     71.5±0.26µs        ? ?/sec    1.00     71.2±0.31µs        ? ?/sec
convert_rows 8192 string_dictionary_sparse_keys(100000 values)                 1.00     71.1±0.09µs        ? ?/sec    1.00     70.9±0.06µs        ? ?/sec
convert_rows 8192 string_dictionary_sparse_keys(1000000 values)                1.00     70.9±0.10µs        ? ?/sec    1.00     71.0±0.08µs        ? ?/sec
convert_rows 8192 string_dictionary_sparse_keys(32768 values)                  1.00     70.8±0.06µs        ? ?/sec    1.00     71.1±0.25µs        ? ?/sec

Per-runner information
row_format — shard 1/1

Node: gk3-benchmark-cluster-nap-1sqo6ofk-2def7ee8-zlmg

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

uname:

Linux bench-c6605839908-4303-vs8lx 6.12.105+ #1 SMP Sat Sep 19 07:55:25 UTC 2026 aarch64 GNU/Linux

BENCH_COMMAND:

cargo bench --features=arrow,async,test_common,experimental,object_store --bench row_format
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
Resource Usage

base (merge-base)

Metric Value
Wall time 165.0s
Peak memory 56.8 MiB
Avg memory 24.8 MiB
CPU user 162.9s
CPU sys 0.0s
Peak spill 0 B

branch

Metric Value
Wall time 150.0s
Peak memory 29.5 MiB
Avg memory 18.6 MiB
CPU user 144.2s
CPU sys 0.0s
Peak spill 0 B

File an issue against this benchmark runner

The focused cases were only needed to establish the cutoff and capture hosted evidence. Remove them from the permanent suite and document why the gather path is guarded.
@github-actions github-actions Bot removed the arrow-core Core crates related to representing arrow data label Nov 3, 2026
Comment thread arrow-row/src/lib.rs Resolved
@Rich-T-kid
Rich-T-kid marked this pull request as ready for review November 3, 2026 14:54
@Rich-T-kid

Copy link
Copy Markdown
Contributor Author

@jayzhan211 this is ready for review so please feel free to take a look

@Rich-T-kid Rich-T-kid changed the title WIP: perf(arrow-row): avoid encoding oversized dictionary values perf(arrow-row): avoid encoding oversized dictionary values Nov 3, 2026
@Rich-T-kid

Copy link
Copy Markdown
Contributor Author

run benchmark row_format
env:
BENCH_FILTER: string_dictionary_sparse_keys

@adriangbot

Copy link
Copy Markdown

🤖 Benchmark starting (GKE) | trigger

Target: row_format

Sharding factor: 1 (1 workers).

Comparing rich-T-kid/row-dictionary-sparse-encode (71401d6) to b65bab9 (merge-base) diff

Run configuration
run benchmark row_format
env:
  BENCH_FILTER: string_dictionary_sparse_keys
shards: 1

Results will be posted when all workers finish.


File an issue against this benchmark runner

@Rich-T-kid

Copy link
Copy Markdown
Contributor Author

run benchmark row_format
env:
BENCH_FILTER: string_dictionary_sparse_keys

@Rich-T-kid

Copy link
Copy Markdown
Contributor Author

run benchmark row_format
env:
BENCH_FILTER: string_dictionary_sparse_keys

1 similar comment
@Rich-T-kid

Copy link
Copy Markdown
Contributor Author

run benchmark row_format
env:
BENCH_FILTER: string_dictionary_sparse_keys

@adriangbot

Copy link
Copy Markdown

🤖 Benchmark starting (GKE) | trigger

Target: row_format

Sharding factor: 1 (1 workers).

Comparing rich-T-kid/row-dictionary-sparse-encode (71401d6) to b65bab9 (merge-base) diff

Run configuration
run benchmark row_format
env:
  BENCH_FILTER: string_dictionary_sparse_keys
shards: 1

Results will be posted when all workers finish.


File an issue against this benchmark runner

@adriangbot

Copy link
Copy Markdown

🤖 Benchmark starting (GKE) | trigger

Target: row_format

Sharding factor: 1 (1 workers).

Comparing rich-T-kid/row-dictionary-sparse-encode (601d0ed) to 258b0d2 (merge-base) diff

Run configuration
run benchmark row_format
env:
  BENCH_FILTER: string_dictionary_sparse_keys
shards: 1

Results will be posted when all workers finish.


File an issue against this benchmark runner

@adriangbot

Copy link
Copy Markdown

🤖 Benchmark starting (GKE) | trigger

Target: row_format

Sharding factor: 1 (1 workers).

Comparing rich-T-kid/row-dictionary-sparse-encode (601d0ed) to 258b0d2 (merge-base) diff

Run configuration
run benchmark row_format
env:
  BENCH_FILTER: string_dictionary_sparse_keys
shards: 1

Results will be posted when all workers finish.


File an issue against this benchmark runner

@adriangbot

Copy link
Copy Markdown

🤖 Benchmark completed (GKE) | trigger

Target: row_format

Comparing rich-T-kid/row-dictionary-sparse-encode (71401d6) to b65bab9 (merge-base) diff

Run configuration
run benchmark row_format
env:
  BENCH_FILTER: string_dictionary_sparse_keys
shards: 1
Details
No matching cases; no measurements run.

Per-runner information
row_format — shard 1/1

Node: gk3-benchmark-cluster-nap-xzxr7f8s-1e582ac0-vtcl

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

uname:

Linux bench-c6621519870-4413-btmnl 6.12.105+ #1 SMP Sat Sep 19 07:55:25 UTC 2026 aarch64 GNU/Linux

BENCH_COMMAND:

cargo bench --features=arrow,async,test_common,experimental,object_store --bench row_format
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
Resource Usage

base (merge-base)

Metric Value
Wall time 5.0s
Peak memory 5.8 MiB
Avg memory 983.3 KiB
CPU user 0.0s
CPU sys 0.0s
Peak spill 0 B

branch

Metric Value
Wall time 5.0s
Peak memory 0 B
Avg memory 0 B
CPU user 0.0s
CPU sys 0.0s
Peak spill 0 B

File an issue against this benchmark runner

@adriangbot

Copy link
Copy Markdown

🤖 Benchmark completed (GKE) | trigger

Target: row_format

Comparing rich-T-kid/row-dictionary-sparse-encode (71401d6) to b65bab9 (merge-base) diff

Run configuration
run benchmark row_format
env:
  BENCH_FILTER: string_dictionary_sparse_keys
shards: 1
Details
No matching cases; no measurements run.

Per-runner information
row_format — shard 1/1

Node: gk3-benchmark-cluster-nap-1rm0t8tn-70a49e36-pc7t

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

uname:

Linux bench-c6621518167-4412-k7nk4 6.12.105+ #1 SMP Sat Sep 19 07:55:25 UTC 2026 aarch64 GNU/Linux

BENCH_COMMAND:

cargo bench --features=arrow,async,test_common,experimental,object_store --bench row_format
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
Resource Usage

base (merge-base)

Metric Value
Wall time 5.0s
Peak memory 5.8 MiB
Avg memory 3.8 MiB
CPU user 0.0s
CPU sys 0.0s
Peak spill 0 B

branch

Metric Value
Wall time 5.0s
Peak memory 0 B
Avg memory 0 B
CPU user 0.0s
CPU sys 0.0s
Peak spill 0 B

File an issue against this benchmark runner

@adriangbot

Copy link
Copy Markdown

🤖 Benchmark completed (GKE) | trigger

Target: row_format

Comparing rich-T-kid/row-dictionary-sparse-encode (601d0ed) to 258b0d2 (merge-base) diff

Run configuration
run benchmark row_format
env:
  BENCH_FILTER: string_dictionary_sparse_keys
shards: 1
Details
No matching cases; no measurements run.

Per-runner information
row_format — shard 1/1

Node: gk3-benchmark-cluster-nap-fcu1jron-5132aa10-mvjb

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

uname:

Linux bench-c6621523191-4414-vqcb2 6.12.105+ #1 SMP Sat Sep 19 07:55:25 UTC 2026 aarch64 GNU/Linux

BENCH_COMMAND:

cargo bench --features=arrow,async,test_common,experimental,object_store --bench row_format
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
Resource Usage

base (merge-base)

Metric Value
Wall time 5.0s
Peak memory 5.9 MiB
Avg memory 1006.0 KiB
CPU user 0.0s
CPU sys 0.0s
Peak spill 0 B

branch

Metric Value
Wall time 5.0s
Peak memory 0 B
Avg memory 0 B
CPU user 0.0s
CPU sys 0.0s
Peak spill 0 B

File an issue against this benchmark runner

@adriangbot

Copy link
Copy Markdown

🤖 Benchmark completed (GKE) | trigger

Target: row_format

Comparing rich-T-kid/row-dictionary-sparse-encode (601d0ed) to 258b0d2 (merge-base) diff

Run configuration
run benchmark row_format
env:
  BENCH_FILTER: string_dictionary_sparse_keys
shards: 1
Details
No matching cases; no measurements run.

Per-runner information
row_format — shard 1/1

Node: gk3-benchmark-cluster-nap-19bflw4d-2c0bb708-qjd6

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

uname:

Linux bench-c6621524648-4415-6dk6h 6.12.105+ #1 SMP Sat Sep 19 07:55:25 UTC 2026 aarch64 GNU/Linux

BENCH_COMMAND:

cargo bench --features=arrow,async,test_common,experimental,object_store --bench row_format
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
Resource Usage

base (merge-base)

Metric Value
Wall time 5.0s
Peak memory 5.9 MiB
Avg memory 1006.7 KiB
CPU user 0.0s
CPU sys 0.0s
Peak spill 0 B

branch

Metric Value
Wall time 5.0s
Peak memory 0 B
Avg memory 0 B
CPU user 0.0s
CPU sys 0.0s
Peak spill 0 B

File an issue against this benchmark runner

@Rich-T-kid

Copy link
Copy Markdown
Contributor Author

run benchmark row_format
env:
BENCH_FILTER: dictionary*

@Rich-T-kid

Copy link
Copy Markdown
Contributor Author

run benchmark row_format
env:
BENCH_FILTER: dictionary

@adriangbot

Copy link
Copy Markdown

Hi @Rich-T-kid, your benchmark configuration could not be parsed (#12043 (comment)).

Error: invalid configuration: unknown field BENCH_FILTER, expected one of env, baseline, changed, resources, shards at line 2 column 1

Usage:

run benchmark <name>           # run specific benchmark(s)
run benchmarks                 # run default suite
run benchmarks <name1> <name2> # run specific benchmarks

Any benchmark name is accepted: bench.sh suite names (e.g. tpch, clickbench_partitioned, wide_schema) and Criterion bench targets (e.g. sql_planner) are resolved automatically. A name that matches neither fails on the runner.

Per-side configuration (run benchmark tpch followed by):

env:
# shared env is inherited by BOTH the build and the run, so build
# flags go here. Builds default to no debuginfo for speed; opt back
# in for hung-job gdb dumps and cap jobs to stay within memory:
CARGO_PROFILE_RELEASE_DEBUG: "1"
CARGO_BUILD_JOBS: "1"
baseline:
ref: v45.0.0
env:
# per-side env only reaches the benchmark run, not the build
DATAFUSION_RUNTIME_MEMORY_LIMIT: 1G
changed:
ref: v46.0.0
env:
DATAFUSION_RUNTIME_MEMORY_LIMIT: 2G

Pod size and CPU architecture (each key is optional and keeps the default when absent; requests and limits are set equal):

resources:
cpu: "16"
memory: "128Gi"
arch: arm64          # arm64 or amd64

Independent benchmark shards (optional; 1–8, default 1):

run benchmark arrow_writer
shards: 4

Each shard builds both revisions, measures its assigned cases, and posts its own report. Resources and the job deadline apply per shard. DataFusion requests specifying a shard count greater than 1 fail with an error. Omit shards or use shards: 1 for DataFusion.


File an issue against this benchmark runner

@adriangbot

Copy link
Copy Markdown

🤖 Benchmark starting (GKE) | trigger

Target: row_format

Sharding factor: 1 (1 workers).

Comparing rich-T-kid/row-dictionary-sparse-encode (9925688) to b010f53 (merge-base) diff

Run configuration
run benchmark row_format
env:
  BENCH_FILTER: dictionary*
shards: 1

Results will be posted when all workers finish.


File an issue against this benchmark runner

@adriangbot

Copy link
Copy Markdown

🤖 Benchmark completed (GKE) | trigger

Target: row_format

Comparing rich-T-kid/row-dictionary-sparse-encode (9925688) to b010f53 (merge-base) diff

Run configuration
run benchmark row_format
env:
  BENCH_FILTER: dictionary*
shards: 1
Details
group                                                                                                                         base                                    changed
-----                                                                                                                         ----                                    -------
append_rows 4096 4096 string_dictionary(20, 0.5), string_dictionary(30, 0), string_dictionary(100, 0), i64(0)                 1.00    176.8±1.46µs        ? ?/sec     1.00    176.4±1.41µs        ? ?/sec
append_rows 4096 string_dictionary(10, 0)                                                                                     1.00     48.3±0.09µs        ? ?/sec     1.00     48.3±0.05µs        ? ?/sec
append_rows 4096 string_dictionary(100, 0)                                                                                    1.00     72.5±0.15µs        ? ?/sec     1.00     72.6±0.19µs        ? ?/sec
append_rows 4096 string_dictionary(100, 0.5)                                                                                  1.00     53.3±0.23µs        ? ?/sec     1.01     53.9±0.26µs        ? ?/sec
append_rows 4096 string_dictionary(30, 0)                                                                                     1.00     54.9±1.29µs        ? ?/sec     1.01     55.5±1.66µs        ? ?/sec
append_rows 4096 string_dictionary_low_cardinality(10, 0)                                                                     1.01     21.5±0.04µs        ? ?/sec     1.00     21.4±0.16µs        ? ?/sec
append_rows 4096 string_dictionary_low_cardinality(100, 0)                                                                    1.00     31.9±0.06µs        ? ?/sec     1.00     31.9±0.03µs        ? ?/sec
append_rows 4096 string_dictionary_low_cardinality(30, 0)                                                                     1.00     24.2±0.03µs        ? ?/sec     1.00     24.1±0.07µs        ? ?/sec
convert_columns 4096 4096 string_dictionary(20, 0.5), string_dictionary(30, 0), string_dictionary(100, 0), i64(0)             1.01    180.4±1.47µs        ? ?/sec     1.00    179.3±1.53µs        ? ?/sec
convert_columns 4096 string_dictionary(10, 0)                                                                                 1.00     49.3±0.07µs        ? ?/sec     1.00     49.2±0.06µs        ? ?/sec
convert_columns 4096 string_dictionary(100, 0)                                                                                1.00     73.6±0.16µs        ? ?/sec     1.02     75.4±0.76µs        ? ?/sec
convert_columns 4096 string_dictionary(100, 0.5)                                                                              1.00     54.3±0.18µs        ? ?/sec     1.01     54.9±0.25µs        ? ?/sec
convert_columns 4096 string_dictionary(30, 0)                                                                                 1.00     55.4±1.28µs        ? ?/sec     1.00     55.3±1.32µs        ? ?/sec
convert_columns 4096 string_dictionary_low_cardinality(10, 0)                                                                 1.00     22.5±0.03µs        ? ?/sec     1.00     22.4±0.04µs        ? ?/sec
convert_columns 4096 string_dictionary_low_cardinality(100, 0)                                                                1.01     33.1±0.12µs        ? ?/sec     1.00     32.9±0.04µs        ? ?/sec
convert_columns 4096 string_dictionary_low_cardinality(30, 0)                                                                 1.03     25.8±0.07µs        ? ?/sec     1.00     25.0±0.04µs        ? ?/sec
convert_columns_prepared 4096 4096 string_dictionary(20, 0.5), string_dictionary(30, 0), string_dictionary(100, 0), i64(0)    1.00    176.4±1.51µs        ? ?/sec     1.00    176.2±1.48µs        ? ?/sec
convert_columns_prepared 4096 string_dictionary(10, 0)                                                                        1.00     48.4±0.08µs        ? ?/sec     1.00     48.3±0.08µs        ? ?/sec
convert_columns_prepared 4096 string_dictionary(100, 0)                                                                       1.00     72.5±0.15µs        ? ?/sec     1.00     72.6±0.19µs        ? ?/sec
convert_columns_prepared 4096 string_dictionary(100, 0.5)                                                                     1.00     53.1±0.20µs        ? ?/sec     1.01     53.7±0.26µs        ? ?/sec
convert_columns_prepared 4096 string_dictionary(30, 0)                                                                        1.01     54.6±1.25µs        ? ?/sec     1.00     54.2±1.25µs        ? ?/sec
convert_columns_prepared 4096 string_dictionary_low_cardinality(10, 0)                                                        1.01     21.6±0.04µs        ? ?/sec     1.00     21.5±0.03µs        ? ?/sec
convert_columns_prepared 4096 string_dictionary_low_cardinality(100, 0)                                                       1.01     32.1±0.25µs        ? ?/sec     1.00     31.9±0.03µs        ? ?/sec
convert_columns_prepared 4096 string_dictionary_low_cardinality(30, 0)                                                        1.01     24.2±0.04µs        ? ?/sec     1.00     24.1±0.03µs        ? ?/sec
convert_columns_prepared 8192 string_dictionary(1000000 values)                                                               33.60     6.8±0.04ms        ? ?/sec     1.00    202.3±1.88µs        ? ?/sec
convert_columns_prepared 8192 string_dictionary(4000000 values)                                                               323.31    65.6±0.48ms        ? ?/sec    1.00    203.0±1.19µs        ? ?/sec
convert_rows 4096 4096 string_dictionary(20, 0.5), string_dictionary(30, 0), string_dictionary(100, 0), i64(0)                1.01    172.0±0.37µs        ? ?/sec     1.00    171.0±0.72µs        ? ?/sec
convert_rows 4096 string_dictionary(10, 0)                                                                                    1.01     36.0±0.42µs        ? ?/sec     1.00     35.8±0.31µs        ? ?/sec
convert_rows 4096 string_dictionary(100, 0)                                                                                   1.00     62.7±0.15µs        ? ?/sec     1.01     63.3±0.09µs        ? ?/sec
convert_rows 4096 string_dictionary(100, 0.5)                                                                                 1.00     43.1±0.19µs        ? ?/sec     1.08     46.3±0.21µs        ? ?/sec
convert_rows 4096 string_dictionary(30, 0)                                                                                    1.00     44.0±0.06µs        ? ?/sec     1.00     44.1±0.19µs        ? ?/sec
convert_rows 4096 string_dictionary_low_cardinality(10, 0)                                                                    1.00     35.6±0.03µs        ? ?/sec     1.10     39.2±0.17µs        ? ?/sec
convert_rows 4096 string_dictionary_low_cardinality(100, 0)                                                                   1.02     63.7±0.19µs        ? ?/sec     1.00     62.6±0.12µs        ? ?/sec
convert_rows 4096 string_dictionary_low_cardinality(30, 0)                                                                    1.00     44.1±0.10µs        ? ?/sec     1.00     44.3±0.68µs        ? ?/sec

Per-runner information
row_format — shard 1/1

Node: gk3-benchmark-cluster-nap-rw3tiycv-5f790bb7-xtb8

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

uname:

Linux bench-c6621954920-4427-p49vv 6.12.105+ #1 SMP Sat Sep 19 07:55:25 UTC 2026 aarch64 GNU/Linux

BENCH_COMMAND:

cargo bench --features=arrow,async,test_common,experimental,object_store --bench row_format
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
Resource Usage

base (merge-base)

Metric Value
Wall time 340.1s
Peak memory 221.7 MiB
Avg memory 25.6 MiB
CPU user 329.1s
CPU sys 6.1s
Peak spill 0 B

branch

Metric Value
Wall time 335.1s
Peak memory 109.1 MiB
Avg memory 24.3 MiB
CPU user 329.3s
CPU sys 0.1s
Peak spill 0 B

File an issue against this benchmark runner

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

looks good to me, some minor comments

fyi @jayzhan211

Comment thread arrow-row/src/lib.rs Resolved
Comment thread arrow-row/src/lib.rs Resolved
Comment thread arrow-row/src/lib.rs Resolved
@Rich-T-kid

Copy link
Copy Markdown
Contributor Author

using take here could be a good idea, especially regarding not copying unnecessary data for null slots (e.g. in case element 0 is a large string)
though it does force bringing in arrow-select as a dependency 🤔

yes I agree that it would make it simpler here but I don't think we should introduce the dependency. I think we should try to optimize this natively and if the results are still not good enough we can consider it.

@Rich-T-kid
Rich-T-kid requested a review from Jefffrey November 4, 2026 16:23
@Jefffrey Jefffrey removed the enhancement New feature/addition label Nov 5, 2026

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

should be good, unless jay wants to take a look

@Rich-T-kid

Copy link
Copy Markdown
Contributor Author

thanks @Jefffrey

@Rich-T-kid
Rich-T-kid added this pull request to the merge queue Nov 5, 2026
Merged via the queue into apache:main with commit 6759872 Nov 5, 2026
21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RowConverter encodes every dictionary value for each batch, not just the values its rows reference

3 participants