Skip to content

perf: optimize spark_lpad (up to 2x faster)#4919

Open
andygrove wants to merge 1 commit into
apache:mainfrom
andygrove:auto-opt/spark_lpad-datafusion-comet-20260714-051345
Open

perf: optimize spark_lpad (up to 2x faster)#4919
andygrove wants to merge 1 commit into
apache:mainfrom
andygrove:auto-opt/spark_lpad-datafusion-comet-20260714-051345

Conversation

@andygrove

@andygrove andygrove commented Jul 14, 2026

Copy link
Copy Markdown
Member

Which issue does this PR close?

N/A

Rationale for this change

Optimize existing expression.

What changes are included in this PR?

Pad rows with one memcpy from a precomputed repeating pad buffer and write pieces directly into the string builder instead of a scratch String, plus an ASCII fast path and a fix for a rows*rows capacity hint in the column-length path.

How are these changes tested?

Existing tests + new unit tests.

Benchmark (criterion):

  • spark_rpad_ default padding: 40.449% faster (base 130815ns -> cand 77902ns)
  • spark_rpad_ length from column, multi-char padding: 41.531% faster (base 128111ns -> cand 74905ns)
  • spark_lpad_ default padding: 37.778% faster (base 126685ns -> cand 78826ns)
  • spark_lpad_ length from column: 31.923% faster (base 110963ns -> cand 75540ns)
  • spark_lpad_ custom padding: 35.618% faster (base 123106ns -> cand 79258ns)
  • spark_rpad_ multi-char padding: 52.516% faster (base 165109ns -> cand 78401ns)
  • spark_lpad_ with truncation: 50.694% faster (base 110062ns -> cand 54268ns)
  • spark_lpad_ multi-char padding: 57.246% faster (base 181356ns -> cand 77536ns)
  • spark_rpad_ length from column: 32.23% faster (base 110303ns -> cand 74752ns)
  • spark_rpad_ custom padding: 40.385% faster (base 130616ns -> cand 77866ns)
  • spark_rpad_ with truncation: 50.556% faster (base 109976ns -> cand 54377ns)

Full criterion output:

spark_lpad: default padding
                        time:   [78.908 µs 79.083 µs 79.261 µs]
                        change: [−37.968% −37.778% −37.621%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 6 outliers among 100 measurements (6.00%)
  6 (6.00%) high mild

spark_lpad: custom padding
                        time:   [78.999 µs 79.093 µs 79.196 µs]
                        change: [−35.699% −35.618% −35.554%] (p = 0.00 < 0.05)
                        Performance has improved.

spark_rpad: default padding
                        time:   [78.086 µs 78.410 µs 78.731 µs]
                        change: [−40.596% −40.449% −40.294%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 20 outliers among 100 measurements (20.00%)
  3 (3.00%) high mild
  17 (17.00%) high severe

spark_rpad: custom padding
                        time:   [77.806 µs 77.855 µs 77.931 µs]
                        change: [−40.474% −40.385% −40.290%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 6 outliers among 100 measurements (6.00%)
  3 (3.00%) high mild
  3 (3.00%) high severe

spark_lpad: multi-char padding
                        time:   [77.424 µs 77.539 µs 77.677 µs]
                        change: [−57.312% −57.246% −57.187%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 3 outliers among 100 measurements (3.00%)
  3 (3.00%) high mild

spark_rpad: multi-char padding
                        time:   [78.306 µs 78.409 µs 78.530 µs]
                        change: [−52.583% −52.516% −52.442%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 7 outliers among 100 measurements (7.00%)
  6 (6.00%) high mild
  1 (1.00%) high severe

spark_lpad: with truncation
                        time:   [54.249 µs 54.317 µs 54.393 µs]
                        change: [−50.755% −50.694% −50.637%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 13 outliers among 100 measurements (13.00%)
  1 (1.00%) low mild
  11 (11.00%) high mild
  1 (1.00%) high severe

spark_rpad: with truncation
                        time:   [54.146 µs 54.203 µs 54.268 µs]
                        change: [−50.698% −50.556% −50.370%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 3 outliers among 100 measurements (3.00%)
  3 (3.00%) high severe

spark_lpad: length from column
                        time:   [75.318 µs 75.499 µs 75.686 µs]
                        change: [−32.039% −31.923% −31.795%] (p = 0.00 < 0.05)
                        Performance has improved.

spark_rpad: length from column
                        time:   [74.721 µs 74.759 µs 74.818 µs]
                        change: [−32.298% −32.230% −32.168%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 4 outliers among 100 measurements (4.00%)
  2 (2.00%) high mild
  2 (2.00%) high severe

spark_rpad: length from column, multi-char padding
                        time:   [74.876 µs 74.937 µs 75.016 µs]
                        change: [−41.976% −41.531% −41.269%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 5 outliers among 100 measurements (5.00%)
  3 (3.00%) high mild
  2 (2.00%) high severe

@andygrove andygrove changed the title perf: optimize spark_lpad in datafusion-comet-spark-expr perf: optimize spark_lpad (up to 2x faster) Jul 14, 2026
@andygrove andygrove marked this pull request as ready for review July 14, 2026 14:09
let mut data_capacity = 0usize;
let mut max_length = 0usize;
for length in int_pad_array.values() {
let length = (*length).max(0) as usize;

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.

Hopefully this every row cast is not expensive on modern CPUs

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

Thanks @andygrove

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants