Skip to content

Conversation

@CuteChuanChuan
Copy link
Contributor

Which issue does this PR close?

Rationale for this change

The CaseExpr implementation is expensive. A common usage pattern (particularly in TPC-DS benchmarks) is to protect against divide-by-zero:

CASE WHEN y > 0 THEN x / y ELSE NULL END

This entire expression can be replaced with a simpler divide operation that returns NULL when the divisor is zero, avoiding the overhead of full CASE evaluation.

What changes are included in this PR?

  1. New EvalMethod::DivideByZeroProtection variant - A specialization for the divide-by-zero protection pattern
  2. Pattern detection - Detects patterns like:
  • CASE WHEN y > 0 THEN x / y ELSE NULL END
  • CASE WHEN y != 0 THEN x / y ELSE NULL END
  • CASE WHEN 0 < y THEN x / y ELSE NULL END
  1. Critical validation - Ensures the divisor in the division matches the operand being checked (addresses feedback from PR#12049)
  2. Safe division implementation - Uses Arrow kernels to perform division that returns NULL on zero:
  • eq to create zero mask
  • zip to replace zeros with ones (avoid division error)
  • div to perform division
  • nullif to set NULL where divisor was zero

Are these changes tested?

Yes, added two new tests:

  • test_divide_by_zero_protection_specialization - Verifies pattern is detected and results are correct
  • test_divide_by_zero_protection_specialization_not_applied - Verifies optimization is NOT applied when divisor doesn't match checked operand (key feedback from PR#12049)

Are there any user-facing changes?

No. This is an internal optimization that produces the same results but with better performance.

@github-actions github-actions bot added the physical-expr Changes to the physical-expr crates label Jan 25, 2026
@CuteChuanChuan CuteChuanChuan force-pushed the raymond/11570-optimize-case-when branch 2 times, most recently from 267d8df to 334785f Compare January 25, 2026 11:33
@Dandandan
Copy link
Contributor

run benchmark tpcds

@alamb-ghbot
Copy link

🤖 ./gh_compare_branch.sh gh_compare_branch.sh Running
Linux aal-dev 6.14.0-1018-gcp #19~24.04.1-Ubuntu SMP Wed Sep 24 23:23:09 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
Comparing raymond/11570-optimize-case-when (334785f) to e5e7636 diff using: tpcds
Results will be posted here when complete

@alamb-ghbot
Copy link

🤖: Benchmark completed

Details

Comparing HEAD and raymond_11570-optimize-case-when
--------------------
Benchmark tpcds_sf1.json
--------------------
┏━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Query     ┃        HEAD ┃ raymond_11570-optimize-case-when ┃        Change ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ QQuery 1  │    73.53 ms │                         72.15 ms │     no change │
│ QQuery 2  │   211.96 ms │                        212.04 ms │     no change │
│ QQuery 3  │   163.11 ms │                        158.57 ms │     no change │
│ QQuery 4  │  1859.54 ms │                       1859.56 ms │     no change │
│ QQuery 5  │   289.80 ms │                        292.57 ms │     no change │
│ QQuery 6  │  1460.86 ms │                       1451.05 ms │     no change │
│ QQuery 7  │   523.20 ms │                        519.77 ms │     no change │
│ QQuery 8  │   174.05 ms │                        174.25 ms │     no change │
│ QQuery 9  │   304.03 ms │                        317.25 ms │     no change │
│ QQuery 10 │   177.88 ms │                        180.29 ms │     no change │
│ QQuery 11 │  1253.95 ms │                       1250.79 ms │     no change │
│ QQuery 12 │    68.28 ms │                         68.87 ms │     no change │
│ QQuery 13 │   556.79 ms │                        557.18 ms │     no change │
│ QQuery 14 │  1886.69 ms │                       1880.89 ms │     no change │
│ QQuery 15 │    31.68 ms │                         31.36 ms │     no change │
│ QQuery 16 │    67.90 ms │                         66.24 ms │     no change │
│ QQuery 17 │   374.36 ms │                        370.23 ms │     no change │
│ QQuery 18 │   199.18 ms │                        200.05 ms │     no change │
│ QQuery 19 │   233.55 ms │                        229.54 ms │     no change │
│ QQuery 20 │    26.44 ms │                         25.91 ms │     no change │
│ QQuery 21 │    39.73 ms │                         38.82 ms │     no change │
│ QQuery 22 │   734.66 ms │                        706.03 ms │     no change │
│ QQuery 23 │  1769.26 ms │                       1780.40 ms │     no change │
│ QQuery 24 │   695.92 ms │                        698.61 ms │     no change │
│ QQuery 25 │   536.61 ms │                        536.98 ms │     no change │
│ QQuery 26 │   128.16 ms │                        130.89 ms │     no change │
│ QQuery 27 │   516.70 ms │                        515.08 ms │     no change │
│ QQuery 28 │   308.95 ms │                        314.87 ms │     no change │
│ QQuery 29 │   462.08 ms │                        452.27 ms │     no change │
│ QQuery 30 │    76.33 ms │                         75.76 ms │     no change │
│ QQuery 31 │   330.66 ms │                        307.32 ms │ +1.08x faster │
│ QQuery 32 │    86.10 ms │                         84.90 ms │     no change │
│ QQuery 33 │   208.08 ms │                        208.13 ms │     no change │
│ QQuery 34 │   160.78 ms │                        158.85 ms │     no change │
│ QQuery 35 │   177.42 ms │                        173.31 ms │     no change │
│ QQuery 36 │   288.57 ms │                        283.71 ms │     no change │
│ QQuery 37 │   268.25 ms │                        263.37 ms │     no change │
│ QQuery 38 │   154.18 ms │                        150.76 ms │     no change │
│ QQuery 39 │   206.35 ms │                        207.82 ms │     no change │
│ QQuery 40 │   182.77 ms │                        182.53 ms │     no change │
│ QQuery 41 │    33.59 ms │                         33.35 ms │     no change │
│ QQuery 42 │   146.85 ms │                        143.80 ms │     no change │
│ QQuery 43 │   129.40 ms │                        125.70 ms │     no change │
│ QQuery 44 │    28.27 ms │                         28.68 ms │     no change │
│ QQuery 45 │    90.93 ms │                         93.64 ms │     no change │
│ QQuery 46 │   326.32 ms │                        320.31 ms │     no change │
│ QQuery 47 │  1002.56 ms │                        992.63 ms │     no change │
│ QQuery 48 │   420.49 ms │                        417.63 ms │     no change │
│ QQuery 49 │   386.66 ms │                        382.37 ms │     no change │
│ QQuery 50 │   351.08 ms │                        329.46 ms │ +1.07x faster │
│ QQuery 51 │   306.92 ms │                        298.73 ms │     no change │
│ QQuery 52 │   146.18 ms │                        145.57 ms │     no change │
│ QQuery 53 │   155.53 ms │                        151.14 ms │     no change │
│ QQuery 54 │   226.95 ms │                        228.22 ms │     no change │
│ QQuery 55 │   146.10 ms │                        144.10 ms │     no change │
│ QQuery 56 │   208.29 ms │                        205.82 ms │     no change │
│ QQuery 57 │   296.35 ms │                        294.90 ms │     no change │
│ QQuery 58 │   503.21 ms │                        515.55 ms │     no change │
│ QQuery 59 │   296.25 ms │                        285.87 ms │     no change │
│ QQuery 60 │   216.64 ms │                        211.77 ms │     no change │
│ QQuery 61 │   249.26 ms │                        245.76 ms │     no change │
│ QQuery 62 │  1264.67 ms │                       1265.81 ms │     no change │
│ QQuery 63 │   156.24 ms │                        154.40 ms │     no change │
│ QQuery 64 │  1215.91 ms │                       1216.99 ms │     no change │
│ QQuery 65 │   354.02 ms │                        345.83 ms │     no change │
│ QQuery 66 │   396.15 ms │                        391.08 ms │     no change │
│ QQuery 67 │   550.29 ms │                        529.99 ms │     no change │
│ QQuery 68 │   374.32 ms │                        371.29 ms │     no change │
│ QQuery 69 │   179.16 ms │                        169.64 ms │ +1.06x faster │
│ QQuery 70 │   499.78 ms │                        485.62 ms │     no change │
│ QQuery 71 │   188.78 ms │                        184.06 ms │     no change │
│ QQuery 72 │  2118.42 ms │                       2108.28 ms │     no change │
│ QQuery 73 │   158.28 ms │                        152.54 ms │     no change │
│ QQuery 74 │   803.43 ms │                        789.61 ms │     no change │
│ QQuery 75 │   419.38 ms │                        405.28 ms │     no change │
│ QQuery 76 │   188.68 ms │                        192.89 ms │     no change │
│ QQuery 77 │   290.51 ms │                        301.41 ms │     no change │
│ QQuery 78 │   956.92 ms │                        947.49 ms │     no change │
│ QQuery 79 │   329.07 ms │                        325.97 ms │     no change │
│ QQuery 80 │   529.17 ms │                        530.97 ms │     no change │
│ QQuery 81 │    55.19 ms │                         54.42 ms │     no change │
│ QQuery 82 │   285.80 ms │                        283.52 ms │     no change │
│ QQuery 83 │    82.97 ms │                         83.56 ms │     no change │
│ QQuery 84 │    76.51 ms │                         74.25 ms │     no change │
│ QQuery 85 │   228.50 ms │                        239.17 ms │     no change │
│ QQuery 86 │    58.58 ms │                         58.22 ms │     no change │
│ QQuery 87 │   161.57 ms │                        148.84 ms │ +1.09x faster │
│ QQuery 88 │   269.38 ms │                        261.30 ms │     no change │
│ QQuery 89 │   172.37 ms │                        170.60 ms │     no change │
│ QQuery 90 │    47.68 ms │                         45.38 ms │     no change │
│ QQuery 91 │   104.84 ms │                        100.60 ms │     no change │
│ QQuery 92 │    86.48 ms │                         84.88 ms │     no change │
│ QQuery 93 │   283.73 ms │                        280.09 ms │     no change │
│ QQuery 94 │    92.47 ms │                         92.04 ms │     no change │
│ QQuery 95 │   252.91 ms │                        246.37 ms │     no change │
│ QQuery 96 │   115.00 ms │                        113.58 ms │     no change │
│ QQuery 97 │   191.15 ms │                        189.40 ms │     no change │
│ QQuery 98 │   220.21 ms │                        220.04 ms │     no change │
│ QQuery 99 │ 13973.38 ms │                      13911.88 ms │     no change │
└───────────┴─────────────┴──────────────────────────────────┴───────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
┃ Benchmark Summary                               ┃            ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩
│ Total Time (HEAD)                               │ 50668.05ms │
│ Total Time (raymond_11570-optimize-case-when)   │ 50311.35ms │
│ Average Time (HEAD)                             │   511.80ms │
│ Average Time (raymond_11570-optimize-case-when) │   508.20ms │
│ Queries Faster                                  │          4 │
│ Queries Slower                                  │          0 │
│ Queries with No Change                          │         95 │
│ Queries with Failure                            │          0 │
└─────────────────────────────────────────────────┴────────────┘

@CuteChuanChuan
Copy link
Contributor Author

Hi @andygrove ,
could you PTAL when you have a chance. Thanks!

@alamb
Copy link
Contributor

alamb commented Jan 26, 2026

run benchmark tpcds

@alamb
Copy link
Contributor

alamb commented Jan 26, 2026

Also FYI @pepijnve

@alamb-ghbot
Copy link

🤖 ./gh_compare_branch.sh gh_compare_branch.sh Running
Linux aal-dev 6.14.0-1018-gcp #19~24.04.1-Ubuntu SMP Wed Sep 24 23:23:09 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
Comparing raymond/11570-optimize-case-when (334785f) to e5e7636 diff using: tpcds
Results will be posted here when complete

@pepijnve
Copy link
Contributor

pepijnve commented Jan 26, 2026

It might be useful to add a microbenchmark to https://github.com/apache/datafusion/blob/main/datafusion/physical-expr/benches/case_when.rs so we can compare before/after. I don't think any of the existing ones will cover this particular pattern.

The TCP-DS queries that contain this pattern (based on grep case *.sql | grep /) are q4, q11, q31, q39, q47, q57, q63, q74, and q89. Looking at the TCP-DS benchmark results it's not clear cut if the extra code provides a meaningful improvement over the ExprOrExpr implementation. Hopefully a microbenchmark can make that more clear.

@alamb-ghbot
Copy link

🤖: Benchmark completed

Details

Comparing HEAD and raymond_11570-optimize-case-when
--------------------
Benchmark tpcds_sf1.json
--------------------
┏━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Query     ┃        HEAD ┃ raymond_11570-optimize-case-when ┃        Change ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ QQuery 1  │    74.22 ms │                         73.09 ms │     no change │
│ QQuery 2  │   217.44 ms │                        216.89 ms │     no change │
│ QQuery 3  │   163.87 ms │                        162.40 ms │     no change │
│ QQuery 4  │  2026.32 ms │                       1960.99 ms │     no change │
│ QQuery 5  │   289.74 ms │                        285.49 ms │     no change │
│ QQuery 6  │  1464.31 ms │                       1486.77 ms │     no change │
│ QQuery 7  │   526.02 ms │                        523.15 ms │     no change │
│ QQuery 8  │   174.99 ms │                        179.57 ms │     no change │
│ QQuery 9  │   298.70 ms │                        297.78 ms │     no change │
│ QQuery 10 │   186.01 ms │                        181.85 ms │     no change │
│ QQuery 11 │  1315.39 ms │                       1318.46 ms │     no change │
│ QQuery 12 │    71.85 ms │                         71.62 ms │     no change │
│ QQuery 13 │   563.56 ms │                        564.29 ms │     no change │
│ QQuery 14 │  1875.27 ms │                       1897.99 ms │     no change │
│ QQuery 15 │    31.57 ms │                         31.44 ms │     no change │
│ QQuery 16 │    66.83 ms │                         66.62 ms │     no change │
│ QQuery 17 │   378.66 ms │                        372.09 ms │     no change │
│ QQuery 18 │   196.21 ms │                        202.44 ms │     no change │
│ QQuery 19 │   236.26 ms │                        236.03 ms │     no change │
│ QQuery 20 │    26.90 ms │                         27.83 ms │     no change │
│ QQuery 21 │    38.51 ms │                         38.91 ms │     no change │
│ QQuery 22 │   734.60 ms │                        721.89 ms │     no change │
│ QQuery 23 │  1770.88 ms │                       1806.40 ms │     no change │
│ QQuery 24 │   707.80 ms │                        719.96 ms │     no change │
│ QQuery 25 │   537.13 ms │                        556.43 ms │     no change │
│ QQuery 26 │   129.58 ms │                        136.20 ms │  1.05x slower │
│ QQuery 27 │   514.56 ms │                        535.05 ms │     no change │
│ QQuery 28 │   314.50 ms │                        323.78 ms │     no change │
│ QQuery 29 │   462.49 ms │                        473.25 ms │     no change │
│ QQuery 30 │    75.88 ms │                         79.38 ms │     no change │
│ QQuery 31 │   325.91 ms │                        328.01 ms │     no change │
│ QQuery 32 │    87.79 ms │                         88.77 ms │     no change │
│ QQuery 33 │   211.68 ms │                        212.82 ms │     no change │
│ QQuery 34 │   163.45 ms │                        160.95 ms │     no change │
│ QQuery 35 │   182.50 ms │                        177.59 ms │     no change │
│ QQuery 36 │   287.85 ms │                        304.90 ms │  1.06x slower │
│ QQuery 37 │   267.86 ms │                        258.72 ms │     no change │
│ QQuery 38 │   152.79 ms │                        161.68 ms │  1.06x slower │
│ QQuery 39 │   207.26 ms │                        224.05 ms │  1.08x slower │
│ QQuery 40 │   177.26 ms │                        185.25 ms │     no change │
│ QQuery 41 │    34.06 ms │                         35.76 ms │     no change │
│ QQuery 42 │   145.49 ms │                        146.99 ms │     no change │
│ QQuery 43 │   128.99 ms │                        127.93 ms │     no change │
│ QQuery 44 │    30.55 ms │                         31.27 ms │     no change │
│ QQuery 45 │    91.00 ms │                         92.33 ms │     no change │
│ QQuery 46 │   322.88 ms │                        341.06 ms │  1.06x slower │
│ QQuery 47 │  1044.84 ms │                       1202.10 ms │  1.15x slower │
│ QQuery 48 │   416.25 ms │                        450.28 ms │  1.08x slower │
│ QQuery 49 │   379.54 ms │                        402.49 ms │  1.06x slower │
│ QQuery 50 │   335.35 ms │                        363.33 ms │  1.08x slower │
│ QQuery 51 │   305.38 ms │                        310.19 ms │     no change │
│ QQuery 52 │   147.91 ms │                        148.05 ms │     no change │
│ QQuery 53 │   156.77 ms │                        155.96 ms │     no change │
│ QQuery 54 │   245.74 ms │                        235.85 ms │     no change │
│ QQuery 55 │   146.14 ms │                        150.66 ms │     no change │
│ QQuery 56 │   211.09 ms │                        223.74 ms │  1.06x slower │
│ QQuery 57 │   300.47 ms │                        328.80 ms │  1.09x slower │
│ QQuery 58 │   501.81 ms │                        542.59 ms │  1.08x slower │
│ QQuery 59 │   288.81 ms │                        317.96 ms │  1.10x slower │
│ QQuery 60 │   216.72 ms │                        231.92 ms │  1.07x slower │
│ QQuery 61 │   252.94 ms │                        266.19 ms │  1.05x slower │
│ QQuery 62 │  1322.10 ms │                       1357.68 ms │     no change │
│ QQuery 63 │   162.08 ms │                        161.27 ms │     no change │
│ QQuery 64 │  1251.30 ms │                       1299.58 ms │     no change │
│ QQuery 65 │   371.23 ms │                        405.98 ms │  1.09x slower │
│ QQuery 66 │   415.97 ms │                        420.40 ms │     no change │
│ QQuery 67 │   556.46 ms │                        573.10 ms │     no change │
│ QQuery 68 │   386.47 ms │                        395.70 ms │     no change │
│ QQuery 69 │   179.11 ms │                        174.83 ms │     no change │
│ QQuery 70 │   509.44 ms │                        507.92 ms │     no change │
│ QQuery 71 │   189.63 ms │                        189.14 ms │     no change │
│ QQuery 72 │  2110.07 ms │                       2179.77 ms │     no change │
│ QQuery 73 │   163.03 ms │                        172.29 ms │  1.06x slower │
│ QQuery 74 │   913.76 ms │                        866.29 ms │ +1.05x faster │
│ QQuery 75 │   442.47 ms │                        414.73 ms │ +1.07x faster │
│ QQuery 76 │   199.37 ms │                        194.69 ms │     no change │
│ QQuery 77 │   308.23 ms │                        292.21 ms │ +1.05x faster │
│ QQuery 78 │   970.51 ms │                        981.48 ms │     no change │
│ QQuery 79 │   352.72 ms │                        340.08 ms │     no change │
│ QQuery 80 │   556.21 ms │                        538.21 ms │     no change │
│ QQuery 81 │    58.77 ms │                         54.13 ms │ +1.09x faster │
│ QQuery 82 │   303.43 ms │                        287.00 ms │ +1.06x faster │
│ QQuery 83 │    89.38 ms │                         84.59 ms │ +1.06x faster │
│ QQuery 84 │    71.06 ms │                         72.36 ms │     no change │
│ QQuery 85 │   245.30 ms │                        244.27 ms │     no change │
│ QQuery 86 │    62.83 ms │                         59.27 ms │ +1.06x faster │
│ QQuery 87 │   169.87 ms │                        156.40 ms │ +1.09x faster │
│ QQuery 88 │   283.60 ms │                        273.98 ms │     no change │
│ QQuery 89 │   184.75 ms │                        175.03 ms │ +1.06x faster │
│ QQuery 90 │    48.74 ms │                         49.63 ms │     no change │
│ QQuery 91 │   107.45 ms │                        102.83 ms │     no change │
│ QQuery 92 │    88.32 ms │                         89.57 ms │     no change │
│ QQuery 93 │   294.04 ms │                        284.99 ms │     no change │
│ QQuery 94 │    97.37 ms │                         93.80 ms │     no change │
│ QQuery 95 │   259.53 ms │                        261.05 ms │     no change │
│ QQuery 96 │   117.48 ms │                        117.55 ms │     no change │
│ QQuery 97 │   199.62 ms │                        194.28 ms │     no change │
│ QQuery 98 │   221.47 ms │                        226.23 ms │     no change │
│ QQuery 99 │ 14026.91 ms │                      14042.42 ms │     no change │
└───────────┴─────────────┴──────────────────────────────────┴───────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
┃ Benchmark Summary                               ┃            ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩
│ Total Time (HEAD)                               │ 51527.23ms │
│ Total Time (raymond_11570-optimize-case-when)   │ 52090.93ms │
│ Average Time (HEAD)                             │   520.48ms │
│ Average Time (raymond_11570-optimize-case-when) │   526.17ms │
│ Queries Faster                                  │          9 │
│ Queries Slower                                  │         17 │
│ Queries with No Change                          │         73 │
│ Queries with Failure                            │          0 │
└─────────────────────────────────────────────────┴────────────┘

- Adds a specialization for the common pattern: CASE WHEN y > 0 THEN x / y ELSE NULL END
- Add EvalMethod::DivideByZeroProtection variant
- Add pattern detection in find_best_eval_method()
- Implement safe_divide using Arrow kernels
- Handle CastExpr wrapping on divisor
@CuteChuanChuan CuteChuanChuan force-pushed the raymond/11570-optimize-case-when branch from 334785f to 6479884 Compare January 28, 2026 14:00
@CuteChuanChuan
Copy link
Contributor Author

CuteChuanChuan commented Jan 28, 2026

Microbenchmark result:

Scenario DivideByZeroProtection ExpressionOrExpression Speedup
0% zeros 8.5 µs 75.9 µs 8.9x faster
10% zeros 18.7 µs 71.0 µs 3.8x faster
50% zeros 55.5 µs 52.4 µs ~same
90% zeros 56.1 µs 22.1 µs 2.5x slower

@CuteChuanChuan
Copy link
Contributor Author

CuteChuanChuan commented Jan 29, 2026

Hi @pepijnve , thanks for pointing out the need for a microbenchmark. I compared DivideByZeroProtection with ExpressionOrExpression and got the result. However, I'm not sure if I'm doing it correctly — could you PTAL? Thanks!

}
}

fn benchmark_divide_by_zero_protection(c: &mut Criterion, batch_size: usize) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you please pull this additional benchmark code code into its own PR we could then use our benchmarking scripts to compare performance of this PR with main?

Thank you 🙏

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi @alamb, thanks for pointing this out. The PR including benchmark code only is at #20076.

Once that's merged, should I rebase this PR on top of main so the benchmarking scripts can compare the optimization against the baseline?

},
);

group.bench_function(
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm trying to spot the difference between this benchmark and the one just above it, they look identical to me. Yet the measurements seem to produce similar values. What causes that?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi @pepijnve ,
The key difference is in which column is used in the WHEN condition:

  • First benchmark (DivideByZeroProtection): checks divisor_col > 0, and since divisor_col is also the divisor in numerator / divisor_col, this matches the pattern and triggers the optimization.
  • Second benchmark (ExpressionOrExpression): checks divisor_copy_col > 0, but the division uses divisor_col. Since the checked column doesn't match the divisor, the optimization is not triggered and it falls back to ExpressionOrExpression.

I'll also add a comment in the code to make this distinction clearer.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah of course. That's really subtle. A comment for future readers is indeed a good idea.

Copy link
Contributor

Choose a reason for hiding this comment

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

A followup question I had, but I'm happy to measure that myself, is what's causing the performance gap? Might be interesting to see if there's something we could do to improve ExprOrExpr for this particular pattern.

@alamb
Copy link
Contributor

alamb commented Jan 30, 2026

Benchmark was added in #20076

github-merge-queue bot pushed a commit that referenced this pull request Jan 30, 2026
## Which issue does this PR close?

Related to #19994 - This PR extracts the benchmark code to allow
performance comparison.

## Rationale for this change

As pointed out by @alamb in #19994, this separates the microbenchmark
code so that the benchmarking scripts can compare the optimization PR
against main with the benchmark already in place.

## What changes are included in this PR?

Adds a microbenchmark for the divide-by-zero protection pattern in
`case_when.rs`:
- Benchmarks with varying percentages of zeros (0%, 10%, 50%, 90%)
- Compares `DivideByZeroProtection` pattern (where checked column
matches divisor) vs `ExpressionOrExpression` fallback (where they don't
match)

## Are these changes tested?

benchmark code only.

## Are there any user-facing changes?

No.
@alamb
Copy link
Contributor

alamb commented Jan 30, 2026

I merged up to get the new benchmarks so I could run them on our runner

@alamb
Copy link
Contributor

alamb commented Jan 30, 2026

run benchmark case_when

@alamb-ghbot

This comment was marked as outdated.

@alamb
Copy link
Contributor

alamb commented Jan 30, 2026

run benchmark case_when

@alamb-ghbot
Copy link

🤖 ./gh_compare_branch_bench.sh compare_branch_bench.sh Running
Linux aal-dev 6.14.0-1018-gcp #19~24.04.1-Ubuntu SMP Wed Sep 24 23:23:09 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
Comparing raymond/11570-optimize-case-when (2e1c119) to a02e683 diff
BENCH_NAME=case_when
BENCH_COMMAND=cargo bench --features=parquet --bench case_when
BENCH_FILTER=
BENCH_BRANCH_NAME=raymond_11570-optimize-case-when
Results will be posted here when complete

@alamb-ghbot
Copy link

🤖: Benchmark completed

Details

group                                                                                                                             main                                   raymond_11570-optimize-case-when
-----                                                                                                                             ----                                   --------------------------------
case_when 8192x100: CASE WHEN c1 < 0 THEN 0 WHEN c1 < 1000 THEN 1 ... WHEN c1 < n * 1000 THEN n ELSE n + 1 END                    1.00    125.6±2.60µs        ? ?/sec    1.01    126.8±2.33µs        ? ?/sec
case_when 8192x100: CASE WHEN c1 <= 500 THEN 1 ELSE 0 END                                                                         1.00     14.7±0.23µs        ? ?/sec    1.00     14.8±0.20µs        ? ?/sec
case_when 8192x100: CASE WHEN c1 <= 500 THEN c2 ELSE c3 END                                                                       1.01     17.4±0.44µs        ? ?/sec    1.00     17.2±0.39µs        ? ?/sec
case_when 8192x100: CASE WHEN c1 <= 500 THEN c2 [ELSE NULL] END                                                                   1.00      6.6±0.04µs        ? ?/sec    1.00      6.6±0.08µs        ? ?/sec
case_when 8192x100: CASE WHEN c1 == 0 THEN 0 WHEN c1 == 1 THEN 1 ... WHEN c1 == n THEN n ELSE n + 1 END                           1.00     48.2±0.28ms        ? ?/sec    1.00     48.1±0.29ms        ? ?/sec
case_when 8192x100: CASE c1 WHEN 0 THEN 0 WHEN 1 THEN 1 ... WHEN n THEN n ELSE n + 1 END                                          1.00     42.8±0.27µs        ? ?/sec    1.01     43.0±0.45µs        ? ?/sec
case_when 8192x100: CASE c1 WHEN 1 THEN c2 WHEN 2 THEN c3 END                                                                     1.03     30.0±0.74µs        ? ?/sec    1.00     29.0±0.48µs        ? ?/sec
case_when 8192x100: CASE c2 WHEN 0 THEN 0 WHEN 1000 THEN 1 ... WHEN n * 1000 THEN n ELSE n + 1 END                                1.00     38.6±0.56µs        ? ?/sec    1.00     38.6±0.41µs        ? ?/sec
case_when 8192x3: CASE WHEN c1 < 0 THEN 0 WHEN c1 < 1000 THEN 1 ... WHEN c1 < n * 1000 THEN n ELSE n + 1 END                      1.00    125.8±1.69µs        ? ?/sec    1.01    126.4±3.72µs        ? ?/sec
case_when 8192x3: CASE WHEN c1 <= 500 THEN 1 ELSE 0 END                                                                           1.00     14.8±0.19µs        ? ?/sec    1.00     14.7±0.07µs        ? ?/sec
case_when 8192x3: CASE WHEN c1 <= 500 THEN c2 ELSE c3 END                                                                         1.01     17.2±0.58µs        ? ?/sec    1.00     17.0±0.33µs        ? ?/sec
case_when 8192x3: CASE WHEN c1 <= 500 THEN c2 [ELSE NULL] END                                                                     1.00      6.6±0.03µs        ? ?/sec    1.00      6.6±0.05µs        ? ?/sec
case_when 8192x3: CASE WHEN c1 == 0 THEN 0 WHEN c1 == 1 THEN 1 ... WHEN c1 == n THEN n ELSE n + 1 END                             1.00     48.9±0.37ms        ? ?/sec    1.00     48.7±0.27ms        ? ?/sec
case_when 8192x3: CASE c1 WHEN 0 THEN 0 WHEN 1 THEN 1 ... WHEN n THEN n ELSE n + 1 END                                            1.01     42.9±0.67µs        ? ?/sec    1.00     42.6±0.40µs        ? ?/sec
case_when 8192x3: CASE c1 WHEN 1 THEN c2 WHEN 2 THEN c3 END                                                                       1.01     29.8±0.56µs        ? ?/sec    1.00     29.5±0.59µs        ? ?/sec
case_when 8192x3: CASE c2 WHEN 0 THEN 0 WHEN 1000 THEN 1 ... WHEN n * 1000 THEN n ELSE n + 1 END                                  1.00     38.7±0.86µs        ? ?/sec    1.00     38.7±0.55µs        ? ?/sec
case_when 8192x50: CASE WHEN c1 < 0 THEN 0 WHEN c1 < 1000 THEN 1 ... WHEN c1 < n * 1000 THEN n ELSE n + 1 END                     1.00    125.5±1.66µs        ? ?/sec    1.01    126.1±1.74µs        ? ?/sec
case_when 8192x50: CASE WHEN c1 <= 500 THEN 1 ELSE 0 END                                                                          1.00     14.8±0.20µs        ? ?/sec    1.00     14.8±0.10µs        ? ?/sec
case_when 8192x50: CASE WHEN c1 <= 500 THEN c2 ELSE c3 END                                                                        1.00     17.2±0.43µs        ? ?/sec    1.00     17.1±0.42µs        ? ?/sec
case_when 8192x50: CASE WHEN c1 <= 500 THEN c2 [ELSE NULL] END                                                                    1.00      6.6±0.03µs        ? ?/sec    1.00      6.6±0.04µs        ? ?/sec
case_when 8192x50: CASE WHEN c1 == 0 THEN 0 WHEN c1 == 1 THEN 1 ... WHEN c1 == n THEN n ELSE n + 1 END                            1.00     48.2±0.53ms        ? ?/sec    1.00     48.1±0.46ms        ? ?/sec
case_when 8192x50: CASE c1 WHEN 0 THEN 0 WHEN 1 THEN 1 ... WHEN n THEN n ELSE n + 1 END                                           1.00     42.8±0.48µs        ? ?/sec    1.00     43.0±0.31µs        ? ?/sec
case_when 8192x50: CASE c1 WHEN 1 THEN c2 WHEN 2 THEN c3 END                                                                      1.00     30.1±1.04µs        ? ?/sec    1.02     30.7±1.28µs        ? ?/sec
case_when 8192x50: CASE c2 WHEN 0 THEN 0 WHEN 1000 THEN 1 ... WHEN n * 1000 THEN n ELSE n + 1 END                                 1.00     38.6±0.66µs        ? ?/sec    1.00     38.7±0.52µs        ? ?/sec
divide_by_zero_protection/8192 rows, 0% zeros: DivideByZeroProtection                                                             4.52    129.3±1.08µs        ? ?/sec    1.00     28.6±0.10µs        ? ?/sec
divide_by_zero_protection/8192 rows, 0% zeros: ExpressionOrExpression                                                             1.00    131.7±1.04µs        ? ?/sec    1.02    134.1±0.61µs        ? ?/sec
divide_by_zero_protection/8192 rows, 10% zeros: DivideByZeroProtection                                                            2.93    125.3±1.03µs        ? ?/sec    1.00     42.7±0.41µs        ? ?/sec
divide_by_zero_protection/8192 rows, 10% zeros: ExpressionOrExpression                                                            1.00    127.2±1.63µs        ? ?/sec    1.02    129.9±0.95µs        ? ?/sec
divide_by_zero_protection/8192 rows, 50% zeros: DivideByZeroProtection                                                            1.00     90.9±1.23µs        ? ?/sec    1.01     91.4±0.81µs        ? ?/sec
divide_by_zero_protection/8192 rows, 50% zeros: ExpressionOrExpression                                                            1.00     92.1±0.42µs        ? ?/sec    1.03     94.8±2.39µs        ? ?/sec
divide_by_zero_protection/8192 rows, 90% zeros: DivideByZeroProtection                                                            1.00     44.4±0.53µs        ? ?/sec    1.83     81.0±0.43µs        ? ?/sec
divide_by_zero_protection/8192 rows, 90% zeros: ExpressionOrExpression                                                            1.00     44.7±0.20µs        ? ?/sec    1.02     45.7±0.75µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 10 entries, all equally true/case_when 8192 rows: in_range: 0.1, nulls: 0           1.00    117.5±2.59µs        ? ?/sec    1.00    117.8±1.04µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 10 entries, all equally true/case_when 8192 rows: in_range: 0.1, nulls: 0.1         1.00    132.6±0.58µs        ? ?/sec    1.01    134.5±1.61µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 10 entries, all equally true/case_when 8192 rows: in_range: 0.1, nulls: 0.5         1.00    137.0±2.48µs        ? ?/sec    1.00    136.4±0.65µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 10 entries, all equally true/case_when 8192 rows: in_range: 0.5, nulls: 0           1.01    118.7±1.91µs        ? ?/sec    1.00    117.9±0.84µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 10 entries, all equally true/case_when 8192 rows: in_range: 0.5, nulls: 0.1         1.00    133.2±1.16µs        ? ?/sec    1.00    133.6±0.54µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 10 entries, all equally true/case_when 8192 rows: in_range: 0.5, nulls: 0.5         1.00    136.5±0.87µs        ? ?/sec    1.00    136.6±1.03µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 10 entries, all equally true/case_when 8192 rows: in_range: 0.9, nulls: 0           1.00    118.6±2.11µs        ? ?/sec    1.00    118.2±1.30µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 10 entries, all equally true/case_when 8192 rows: in_range: 0.9, nulls: 0.1         1.00    133.4±1.25µs        ? ?/sec    1.00    133.8±0.47µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 10 entries, all equally true/case_when 8192 rows: in_range: 1, nulls: 0             1.00    118.4±1.60µs        ? ?/sec    1.00    118.1±0.76µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 10 entries, only first 2 are true/case_when 8192 rows: in_range: 0.1, nulls: 0      1.00    110.3±3.03µs        ? ?/sec    1.00    109.9±0.85µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 10 entries, only first 2 are true/case_when 8192 rows: in_range: 0.1, nulls: 0.1    1.00    119.6±0.97µs        ? ?/sec    1.01    120.5±0.77µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 10 entries, only first 2 are true/case_when 8192 rows: in_range: 0.1, nulls: 0.5    1.00    120.9±1.56µs        ? ?/sec    1.00    120.7±1.07µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 10 entries, only first 2 are true/case_when 8192 rows: in_range: 0.5, nulls: 0      1.00    110.7±1.62µs        ? ?/sec    1.00    110.5±1.28µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 10 entries, only first 2 are true/case_when 8192 rows: in_range: 0.5, nulls: 0.1    1.00    119.9±0.93µs        ? ?/sec    1.01    121.1±2.06µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 10 entries, only first 2 are true/case_when 8192 rows: in_range: 0.5, nulls: 0.5    1.00    120.8±1.10µs        ? ?/sec    1.00    120.8±1.40µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 10 entries, only first 2 are true/case_when 8192 rows: in_range: 0.9, nulls: 0      1.00    110.1±1.58µs        ? ?/sec    1.00    110.5±1.32µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 10 entries, only first 2 are true/case_when 8192 rows: in_range: 0.9, nulls: 0.1    1.00    120.2±1.71µs        ? ?/sec    1.01    121.1±1.08µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 10 entries, only first 2 are true/case_when 8192 rows: in_range: 1, nulls: 0        1.00    110.5±1.75µs        ? ?/sec    1.00    110.6±1.65µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 20 entries, all equally true/case_when 8192 rows: in_range: 0.1, nulls: 0           1.01    119.3±1.57µs        ? ?/sec    1.00    117.9±0.98µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 20 entries, all equally true/case_when 8192 rows: in_range: 0.1, nulls: 0.1         1.00    132.9±1.24µs        ? ?/sec    1.01    133.8±2.43µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 20 entries, all equally true/case_when 8192 rows: in_range: 0.1, nulls: 0.5         1.00    146.8±1.89µs        ? ?/sec    1.00    147.0±1.16µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 20 entries, all equally true/case_when 8192 rows: in_range: 0.5, nulls: 0           1.01    119.0±0.73µs        ? ?/sec    1.00    117.9±1.35µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 20 entries, all equally true/case_when 8192 rows: in_range: 0.5, nulls: 0.1         1.00    133.2±3.28µs        ? ?/sec    1.00    133.2±0.83µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 20 entries, all equally true/case_when 8192 rows: in_range: 0.5, nulls: 0.5         1.00    146.4±0.89µs        ? ?/sec    1.01    147.3±1.78µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 20 entries, all equally true/case_when 8192 rows: in_range: 0.9, nulls: 0           1.01    119.2±1.32µs        ? ?/sec    1.00    118.0±0.92µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 20 entries, all equally true/case_when 8192 rows: in_range: 0.9, nulls: 0.1         1.00    132.9±1.85µs        ? ?/sec    1.00    133.5±1.57µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 20 entries, all equally true/case_when 8192 rows: in_range: 1, nulls: 0             1.01    118.9±1.16µs        ? ?/sec    1.00    117.9±0.86µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 20 entries, only first 2 are true/case_when 8192 rows: in_range: 0.1, nulls: 0      1.00    109.8±1.42µs        ? ?/sec    1.00    110.3±1.89µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 20 entries, only first 2 are true/case_when 8192 rows: in_range: 0.1, nulls: 0.1    1.00    119.9±0.66µs        ? ?/sec    1.01    121.1±3.29µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 20 entries, only first 2 are true/case_when 8192 rows: in_range: 0.1, nulls: 0.5    1.00    120.7±0.81µs        ? ?/sec    1.00    120.8±1.02µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 20 entries, only first 2 are true/case_when 8192 rows: in_range: 0.5, nulls: 0      1.00    110.9±1.58µs        ? ?/sec    1.00    110.8±2.16µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 20 entries, only first 2 are true/case_when 8192 rows: in_range: 0.5, nulls: 0.1    1.00    119.5±0.88µs        ? ?/sec    1.01    120.8±1.94µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 20 entries, only first 2 are true/case_when 8192 rows: in_range: 0.5, nulls: 0.5    1.00    120.9±0.66µs        ? ?/sec    1.00    121.0±1.64µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 20 entries, only first 2 are true/case_when 8192 rows: in_range: 0.9, nulls: 0      1.00    110.4±1.88µs        ? ?/sec    1.01    110.9±1.86µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 20 entries, only first 2 are true/case_when 8192 rows: in_range: 0.9, nulls: 0.1    1.00    120.0±2.04µs        ? ?/sec    1.01    121.1±1.12µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 20 entries, only first 2 are true/case_when 8192 rows: in_range: 1, nulls: 0        1.00    109.9±1.47µs        ? ?/sec    1.01    111.4±5.06µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 5 entries, all equally true/case_when 8192 rows: in_range: 0.1, nulls: 0            1.00    119.1±3.21µs        ? ?/sec    1.00    118.9±0.80µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 5 entries, all equally true/case_when 8192 rows: in_range: 0.1, nulls: 0.1          1.00    130.6±1.26µs        ? ?/sec    1.01    131.9±1.41µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 5 entries, all equally true/case_when 8192 rows: in_range: 0.1, nulls: 0.5          1.00    129.8±0.59µs        ? ?/sec    1.00    130.1±1.17µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 5 entries, all equally true/case_when 8192 rows: in_range: 0.5, nulls: 0            1.00    119.1±3.23µs        ? ?/sec    1.00    118.9±2.34µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 5 entries, all equally true/case_when 8192 rows: in_range: 0.5, nulls: 0.1          1.00    130.6±1.20µs        ? ?/sec    1.01    131.6±1.85µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 5 entries, all equally true/case_when 8192 rows: in_range: 0.5, nulls: 0.5          1.00    129.9±0.77µs        ? ?/sec    1.00    130.0±1.06µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 5 entries, all equally true/case_when 8192 rows: in_range: 0.9, nulls: 0            1.01    119.3±3.50µs        ? ?/sec    1.00    118.7±1.41µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 5 entries, all equally true/case_when 8192 rows: in_range: 0.9, nulls: 0.1          1.00    130.6±1.12µs        ? ?/sec    1.01    132.0±1.98µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 5 entries, all equally true/case_when 8192 rows: in_range: 1, nulls: 0              1.00    119.0±3.16µs        ? ?/sec    1.00    118.8±1.01µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 5 entries, only first 2 are true/case_when 8192 rows: in_range: 0.1, nulls: 0       1.00    110.1±1.83µs        ? ?/sec    1.00    110.3±1.40µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 5 entries, only first 2 are true/case_when 8192 rows: in_range: 0.1, nulls: 0.1     1.00    119.9±1.59µs        ? ?/sec    1.01    120.6±1.39µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 5 entries, only first 2 are true/case_when 8192 rows: in_range: 0.1, nulls: 0.5     1.00    120.7±0.76µs        ? ?/sec    1.00    120.5±0.71µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 5 entries, only first 2 are true/case_when 8192 rows: in_range: 0.5, nulls: 0       1.00    110.0±1.85µs        ? ?/sec    1.01    110.9±1.50µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 5 entries, only first 2 are true/case_when 8192 rows: in_range: 0.5, nulls: 0.1     1.00    119.8±0.73µs        ? ?/sec    1.01    120.8±1.60µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 5 entries, only first 2 are true/case_when 8192 rows: in_range: 0.5, nulls: 0.5     1.00    120.9±1.51µs        ? ?/sec    1.00    120.7±1.36µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 5 entries, only first 2 are true/case_when 8192 rows: in_range: 0.9, nulls: 0       1.00    110.5±2.08µs        ? ?/sec    1.01    111.5±3.77µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 5 entries, only first 2 are true/case_when 8192 rows: in_range: 0.9, nulls: 0.1     1.00    119.9±0.74µs        ? ?/sec    1.01    120.7±0.65µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 5 entries, only first 2 are true/case_when 8192 rows: in_range: 1, nulls: 0         1.00    109.8±1.47µs        ? ?/sec    1.01    110.6±1.30µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 10 entries, all equally true/case_when 8192 rows: in_range: 0.1, nulls: 0           1.01    146.1±4.25µs        ? ?/sec    1.00    145.3±2.26µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 10 entries, all equally true/case_when 8192 rows: in_range: 0.1, nulls: 0.1         1.00    149.3±3.63µs        ? ?/sec    1.01    150.8±2.67µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 10 entries, all equally true/case_when 8192 rows: in_range: 0.1, nulls: 0.5         1.00    134.0±1.47µs        ? ?/sec    1.03    138.3±2.10µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 10 entries, all equally true/case_when 8192 rows: in_range: 0.5, nulls: 0           1.00    144.2±2.51µs        ? ?/sec    1.01    146.0±3.01µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 10 entries, all equally true/case_when 8192 rows: in_range: 0.5, nulls: 0.1         1.00    150.5±5.40µs        ? ?/sec    1.00    150.3±2.17µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 10 entries, all equally true/case_when 8192 rows: in_range: 0.5, nulls: 0.5         1.00    134.0±1.58µs        ? ?/sec    1.03    137.4±2.23µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 10 entries, all equally true/case_when 8192 rows: in_range: 0.9, nulls: 0           1.00    144.9±3.90µs        ? ?/sec    1.01    146.2±2.94µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 10 entries, all equally true/case_when 8192 rows: in_range: 0.9, nulls: 0.1         1.00    149.3±2.68µs        ? ?/sec    1.01    150.9±3.20µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 10 entries, all equally true/case_when 8192 rows: in_range: 1, nulls: 0             1.00    144.5±3.65µs        ? ?/sec    1.01    145.5±2.32µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 10 entries, only first 2 are true/case_when 8192 rows: in_range: 0.1, nulls: 0      1.00    136.8±3.16µs        ? ?/sec    1.00    136.7±1.20µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 10 entries, only first 2 are true/case_when 8192 rows: in_range: 0.1, nulls: 0.1    1.00    140.4±2.48µs        ? ?/sec    1.02    143.6±4.05µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 10 entries, only first 2 are true/case_when 8192 rows: in_range: 0.1, nulls: 0.5    1.00    129.8±0.51µs        ? ?/sec    1.04    134.8±1.70µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 10 entries, only first 2 are true/case_when 8192 rows: in_range: 0.5, nulls: 0      1.00    135.6±1.16µs        ? ?/sec    1.02    137.8±1.35µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 10 entries, only first 2 are true/case_when 8192 rows: in_range: 0.5, nulls: 0.1    1.00    140.1±2.87µs        ? ?/sec    1.00    140.2±0.94µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 10 entries, only first 2 are true/case_when 8192 rows: in_range: 0.5, nulls: 0.5    1.00    129.5±0.59µs        ? ?/sec    1.03    133.4±0.80µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 10 entries, only first 2 are true/case_when 8192 rows: in_range: 0.9, nulls: 0      1.00    135.7±2.60µs        ? ?/sec    1.03    139.7±4.91µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 10 entries, only first 2 are true/case_when 8192 rows: in_range: 0.9, nulls: 0.1    1.00    138.5±1.39µs        ? ?/sec    1.01    140.4±0.92µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 10 entries, only first 2 are true/case_when 8192 rows: in_range: 1, nulls: 0        1.00    140.8±5.40µs        ? ?/sec    1.00    140.4±3.40µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 20 entries, all equally true/case_when 8192 rows: in_range: 0.1, nulls: 0           1.00    142.6±2.59µs        ? ?/sec    1.02    145.7±3.08µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 20 entries, all equally true/case_when 8192 rows: in_range: 0.1, nulls: 0.1         1.00    145.8±3.01µs        ? ?/sec    1.02    148.3±2.69µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 20 entries, all equally true/case_when 8192 rows: in_range: 0.1, nulls: 0.5         1.00    132.4±3.90µs        ? ?/sec    1.03    136.2±1.34µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 20 entries, all equally true/case_when 8192 rows: in_range: 0.5, nulls: 0           1.00    143.3±3.73µs        ? ?/sec    1.04    148.9±5.29µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 20 entries, all equally true/case_when 8192 rows: in_range: 0.5, nulls: 0.1         1.00    146.9±3.62µs        ? ?/sec    1.00    147.6±2.22µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 20 entries, all equally true/case_when 8192 rows: in_range: 0.5, nulls: 0.5         1.00    133.1±2.19µs        ? ?/sec    1.02    136.2±1.62µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 20 entries, all equally true/case_when 8192 rows: in_range: 0.9, nulls: 0           1.00    143.5±6.72µs        ? ?/sec    1.03   148.2±10.42µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 20 entries, all equally true/case_when 8192 rows: in_range: 0.9, nulls: 0.1         1.03    153.0±5.47µs        ? ?/sec    1.00    148.5±2.89µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 20 entries, all equally true/case_when 8192 rows: in_range: 1, nulls: 0             1.00    141.6±2.76µs        ? ?/sec    1.02    144.7±2.00µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 20 entries, only first 2 are true/case_when 8192 rows: in_range: 0.1, nulls: 0      1.00    134.6±1.16µs        ? ?/sec    1.01    136.3±1.05µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 20 entries, only first 2 are true/case_when 8192 rows: in_range: 0.1, nulls: 0.1    1.00    139.3±1.58µs        ? ?/sec    1.01    140.8±1.04µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 20 entries, only first 2 are true/case_when 8192 rows: in_range: 0.1, nulls: 0.5    1.00    130.3±1.49µs        ? ?/sec    1.03    134.4±0.69µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 20 entries, only first 2 are true/case_when 8192 rows: in_range: 0.5, nulls: 0      1.00    135.6±1.34µs        ? ?/sec    1.01    137.4±1.80µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 20 entries, only first 2 are true/case_when 8192 rows: in_range: 0.5, nulls: 0.1    1.00    138.8±1.73µs        ? ?/sec    1.02    141.2±0.94µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 20 entries, only first 2 are true/case_when 8192 rows: in_range: 0.5, nulls: 0.5    1.00    130.7±1.46µs        ? ?/sec    1.02    133.6±1.26µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 20 entries, only first 2 are true/case_when 8192 rows: in_range: 0.9, nulls: 0      1.00    133.8±0.80µs        ? ?/sec    1.02    136.3±1.00µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 20 entries, only first 2 are true/case_when 8192 rows: in_range: 0.9, nulls: 0.1    1.00    138.0±0.88µs        ? ?/sec    1.02    140.4±1.11µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 20 entries, only first 2 are true/case_when 8192 rows: in_range: 1, nulls: 0        1.00    134.5±1.57µs        ? ?/sec    1.01    136.3±0.88µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 5 entries, all equally true/case_when 8192 rows: in_range: 0.1, nulls: 0            1.00    143.8±3.23µs        ? ?/sec    1.02    146.5±4.67µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 5 entries, all equally true/case_when 8192 rows: in_range: 0.1, nulls: 0.1          1.00    146.7±1.34µs        ? ?/sec    1.02    149.1±1.57µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 5 entries, all equally true/case_when 8192 rows: in_range: 0.1, nulls: 0.5          1.00    135.6±3.41µs        ? ?/sec    1.02    137.9±1.51µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 5 entries, all equally true/case_when 8192 rows: in_range: 0.5, nulls: 0            1.00    143.9±3.81µs        ? ?/sec    1.01    145.7±1.08µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 5 entries, all equally true/case_when 8192 rows: in_range: 0.5, nulls: 0.1          1.00    146.9±3.20µs        ? ?/sec    1.02    149.6±3.13µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 5 entries, all equally true/case_when 8192 rows: in_range: 0.5, nulls: 0.5          1.00    134.5±2.29µs        ? ?/sec    1.02    137.2±1.52µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 5 entries, all equally true/case_when 8192 rows: in_range: 0.9, nulls: 0            1.00    142.9±0.88µs        ? ?/sec    1.02    145.8±3.00µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 5 entries, all equally true/case_when 8192 rows: in_range: 0.9, nulls: 0.1          1.00    147.4±1.01µs        ? ?/sec    1.01    149.6±2.77µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 5 entries, all equally true/case_when 8192 rows: in_range: 1, nulls: 0              1.00    143.3±4.03µs        ? ?/sec    1.02    146.2±4.03µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 5 entries, only first 2 are true/case_when 8192 rows: in_range: 0.1, nulls: 0       1.00    135.8±1.26µs        ? ?/sec    1.01    137.5±3.38µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 5 entries, only first 2 are true/case_when 8192 rows: in_range: 0.1, nulls: 0.1     1.00    139.3±1.63µs        ? ?/sec    1.01    141.2±1.18µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 5 entries, only first 2 are true/case_when 8192 rows: in_range: 0.1, nulls: 0.5     1.00    129.8±0.60µs        ? ?/sec    1.04    135.0±1.80µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 5 entries, only first 2 are true/case_when 8192 rows: in_range: 0.5, nulls: 0       1.00    136.2±4.12µs        ? ?/sec    1.01    138.0±1.92µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 5 entries, only first 2 are true/case_when 8192 rows: in_range: 0.5, nulls: 0.1     1.00    139.9±1.04µs        ? ?/sec    1.00    140.5±1.59µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 5 entries, only first 2 are true/case_when 8192 rows: in_range: 0.5, nulls: 0.5     1.00    129.7±1.00µs        ? ?/sec    1.03    133.4±0.47µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 5 entries, only first 2 are true/case_when 8192 rows: in_range: 0.9, nulls: 0       1.00    134.6±1.08µs        ? ?/sec    1.01    136.0±1.19µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 5 entries, only first 2 are true/case_when 8192 rows: in_range: 0.9, nulls: 0.1     1.00    139.0±2.62µs        ? ?/sec    1.03    142.8±4.67µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 5 entries, only first 2 are true/case_when 8192 rows: in_range: 1, nulls: 0         1.00    135.6±3.86µs        ? ?/sec    1.01    136.4±1.07µs        ? ?/sec

@alamb-ghbot
Copy link

🤖 ./gh_compare_branch_bench.sh compare_branch_bench.sh Running
Linux aal-dev 6.14.0-1018-gcp #19~24.04.1-Ubuntu SMP Wed Sep 24 23:23:09 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
Comparing raymond/11570-optimize-case-when (2e1c119) to a02e683 diff
BENCH_NAME=case_when
BENCH_COMMAND=cargo bench --features=parquet --bench case_when
BENCH_FILTER=
BENCH_BRANCH_NAME=raymond_11570-optimize-case-when
Results will be posted here when complete

@alamb-ghbot
Copy link

🤖: Benchmark completed

Details

group                                                                                                                             main                                   raymond_11570-optimize-case-when
-----                                                                                                                             ----                                   --------------------------------
case_when 8192x100: CASE WHEN c1 < 0 THEN 0 WHEN c1 < 1000 THEN 1 ... WHEN c1 < n * 1000 THEN n ELSE n + 1 END                    1.00    125.6±2.04µs        ? ?/sec    1.01    126.9±2.28µs        ? ?/sec
case_when 8192x100: CASE WHEN c1 <= 500 THEN 1 ELSE 0 END                                                                         1.00     14.7±0.16µs        ? ?/sec    1.00     14.8±0.06µs        ? ?/sec
case_when 8192x100: CASE WHEN c1 <= 500 THEN c2 ELSE c3 END                                                                       1.00     17.3±0.53µs        ? ?/sec    1.03     17.7±0.49µs        ? ?/sec
case_when 8192x100: CASE WHEN c1 <= 500 THEN c2 [ELSE NULL] END                                                                   1.00      6.6±0.03µs        ? ?/sec    1.00      6.6±0.06µs        ? ?/sec
case_when 8192x100: CASE WHEN c1 == 0 THEN 0 WHEN c1 == 1 THEN 1 ... WHEN c1 == n THEN n ELSE n + 1 END                           1.00     47.9±0.62ms        ? ?/sec    1.01     48.2±0.69ms        ? ?/sec
case_when 8192x100: CASE c1 WHEN 0 THEN 0 WHEN 1 THEN 1 ... WHEN n THEN n ELSE n + 1 END                                          1.00     43.0±0.27µs        ? ?/sec    1.00     43.2±0.90µs        ? ?/sec
case_when 8192x100: CASE c1 WHEN 1 THEN c2 WHEN 2 THEN c3 END                                                                     1.00     29.7±0.90µs        ? ?/sec    1.01     29.8±0.59µs        ? ?/sec
case_when 8192x100: CASE c2 WHEN 0 THEN 0 WHEN 1000 THEN 1 ... WHEN n * 1000 THEN n ELSE n + 1 END                                1.02     39.7±0.73µs        ? ?/sec    1.00     38.8±1.03µs        ? ?/sec
case_when 8192x3: CASE WHEN c1 < 0 THEN 0 WHEN c1 < 1000 THEN 1 ... WHEN c1 < n * 1000 THEN n ELSE n + 1 END                      1.00    125.3±1.40µs        ? ?/sec    1.01    126.8±2.43µs        ? ?/sec
case_when 8192x3: CASE WHEN c1 <= 500 THEN 1 ELSE 0 END                                                                           1.00     14.7±0.19µs        ? ?/sec    1.00     14.7±0.23µs        ? ?/sec
case_when 8192x3: CASE WHEN c1 <= 500 THEN c2 ELSE c3 END                                                                         1.00     16.9±0.47µs        ? ?/sec    1.02     17.3±0.38µs        ? ?/sec
case_when 8192x3: CASE WHEN c1 <= 500 THEN c2 [ELSE NULL] END                                                                     1.00      6.6±0.05µs        ? ?/sec    1.00      6.6±0.06µs        ? ?/sec
case_when 8192x3: CASE WHEN c1 == 0 THEN 0 WHEN c1 == 1 THEN 1 ... WHEN c1 == n THEN n ELSE n + 1 END                             1.00     48.0±0.88ms        ? ?/sec    1.02     48.8±0.33ms        ? ?/sec
case_when 8192x3: CASE c1 WHEN 0 THEN 0 WHEN 1 THEN 1 ... WHEN n THEN n ELSE n + 1 END                                            1.00     43.1±0.26µs        ? ?/sec    1.00     43.1±0.44µs        ? ?/sec
case_when 8192x3: CASE c1 WHEN 1 THEN c2 WHEN 2 THEN c3 END                                                                       1.00     30.1±0.73µs        ? ?/sec    1.00     30.1±0.45µs        ? ?/sec
case_when 8192x3: CASE c2 WHEN 0 THEN 0 WHEN 1000 THEN 1 ... WHEN n * 1000 THEN n ELSE n + 1 END                                  1.00     38.6±0.73µs        ? ?/sec    1.00     38.7±1.10µs        ? ?/sec
case_when 8192x50: CASE WHEN c1 < 0 THEN 0 WHEN c1 < 1000 THEN 1 ... WHEN c1 < n * 1000 THEN n ELSE n + 1 END                     1.00    125.9±1.46µs        ? ?/sec    1.01    126.6±1.50µs        ? ?/sec
case_when 8192x50: CASE WHEN c1 <= 500 THEN 1 ELSE 0 END                                                                          1.01     14.9±0.48µs        ? ?/sec    1.00     14.8±0.06µs        ? ?/sec
case_when 8192x50: CASE WHEN c1 <= 500 THEN c2 ELSE c3 END                                                                        1.01     17.3±0.60µs        ? ?/sec    1.00     17.2±0.31µs        ? ?/sec
case_when 8192x50: CASE WHEN c1 <= 500 THEN c2 [ELSE NULL] END                                                                    1.00      6.6±0.08µs        ? ?/sec    1.00      6.6±0.02µs        ? ?/sec
case_when 8192x50: CASE WHEN c1 == 0 THEN 0 WHEN c1 == 1 THEN 1 ... WHEN c1 == n THEN n ELSE n + 1 END                            1.00     47.9±0.54ms        ? ?/sec    1.01     48.5±0.92ms        ? ?/sec
case_when 8192x50: CASE c1 WHEN 0 THEN 0 WHEN 1 THEN 1 ... WHEN n THEN n ELSE n + 1 END                                           1.00     43.0±1.40µs        ? ?/sec    1.00     43.0±0.83µs        ? ?/sec
case_when 8192x50: CASE c1 WHEN 1 THEN c2 WHEN 2 THEN c3 END                                                                      1.01     30.2±0.77µs        ? ?/sec    1.00     29.9±1.08µs        ? ?/sec
case_when 8192x50: CASE c2 WHEN 0 THEN 0 WHEN 1000 THEN 1 ... WHEN n * 1000 THEN n ELSE n + 1 END                                 1.00     38.6±0.43µs        ? ?/sec    1.00     38.5±0.99µs        ? ?/sec
divide_by_zero_protection/8192 rows, 0% zeros: DivideByZeroProtection                                                             4.53    129.4±1.25µs        ? ?/sec    1.00     28.6±0.06µs        ? ?/sec
divide_by_zero_protection/8192 rows, 0% zeros: ExpressionOrExpression                                                             1.00    131.5±1.67µs        ? ?/sec    1.02    134.8±3.11µs        ? ?/sec
divide_by_zero_protection/8192 rows, 10% zeros: DivideByZeroProtection                                                            2.92    124.9±2.16µs        ? ?/sec    1.00     42.8±0.69µs        ? ?/sec
divide_by_zero_protection/8192 rows, 10% zeros: ExpressionOrExpression                                                            1.00    126.5±1.00µs        ? ?/sec    1.03    129.7±0.80µs        ? ?/sec
divide_by_zero_protection/8192 rows, 50% zeros: DivideByZeroProtection                                                            1.00     91.1±0.87µs        ? ?/sec    1.01     91.8±1.48µs        ? ?/sec
divide_by_zero_protection/8192 rows, 50% zeros: ExpressionOrExpression                                                            1.00     92.3±0.33µs        ? ?/sec    1.03     95.4±4.21µs        ? ?/sec
divide_by_zero_protection/8192 rows, 90% zeros: DivideByZeroProtection                                                            1.00     44.7±0.38µs        ? ?/sec    1.82     81.5±2.96µs        ? ?/sec
divide_by_zero_protection/8192 rows, 90% zeros: ExpressionOrExpression                                                            1.00     45.0±0.43µs        ? ?/sec    1.01     45.5±0.33µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 10 entries, all equally true/case_when 8192 rows: in_range: 0.1, nulls: 0           1.00    118.6±1.48µs        ? ?/sec    1.01    120.1±2.45µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 10 entries, all equally true/case_when 8192 rows: in_range: 0.1, nulls: 0.1         1.00    133.6±4.54µs        ? ?/sec    1.01    134.4±1.95µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 10 entries, all equally true/case_when 8192 rows: in_range: 0.1, nulls: 0.5         1.00    136.4±2.36µs        ? ?/sec    1.00    136.4±1.43µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 10 entries, all equally true/case_when 8192 rows: in_range: 0.5, nulls: 0           1.00    118.7±1.59µs        ? ?/sec    1.01    120.5±2.10µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 10 entries, all equally true/case_when 8192 rows: in_range: 0.5, nulls: 0.1         1.00    133.5±2.46µs        ? ?/sec    1.01    134.6±2.34µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 10 entries, all equally true/case_when 8192 rows: in_range: 0.5, nulls: 0.5         1.00    136.3±0.61µs        ? ?/sec    1.00    136.8±1.90µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 10 entries, all equally true/case_when 8192 rows: in_range: 0.9, nulls: 0           1.00    118.5±1.50µs        ? ?/sec    1.02    120.3±2.25µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 10 entries, all equally true/case_when 8192 rows: in_range: 0.9, nulls: 0.1         1.00    132.8±0.74µs        ? ?/sec    1.02    135.6±1.53µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 10 entries, all equally true/case_when 8192 rows: in_range: 1, nulls: 0             1.00    118.9±3.06µs        ? ?/sec    1.01    119.8±1.56µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 10 entries, only first 2 are true/case_when 8192 rows: in_range: 0.1, nulls: 0      1.00    110.2±1.32µs        ? ?/sec    1.00    110.1±1.43µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 10 entries, only first 2 are true/case_when 8192 rows: in_range: 0.1, nulls: 0.1    1.00    119.7±0.68µs        ? ?/sec    1.01    120.4±1.12µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 10 entries, only first 2 are true/case_when 8192 rows: in_range: 0.1, nulls: 0.5    1.00    120.6±0.53µs        ? ?/sec    1.00    120.6±1.61µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 10 entries, only first 2 are true/case_when 8192 rows: in_range: 0.5, nulls: 0      1.00    110.2±1.27µs        ? ?/sec    1.01    111.2±2.59µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 10 entries, only first 2 are true/case_when 8192 rows: in_range: 0.5, nulls: 0.1    1.00    119.5±0.54µs        ? ?/sec    1.01    120.6±1.29µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 10 entries, only first 2 are true/case_when 8192 rows: in_range: 0.5, nulls: 0.5    1.00    120.8±0.74µs        ? ?/sec    1.00    120.6±1.37µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 10 entries, only first 2 are true/case_when 8192 rows: in_range: 0.9, nulls: 0      1.00    110.2±1.79µs        ? ?/sec    1.01    110.8±1.49µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 10 entries, only first 2 are true/case_when 8192 rows: in_range: 0.9, nulls: 0.1    1.00    120.0±1.29µs        ? ?/sec    1.01    121.0±2.93µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 10 entries, only first 2 are true/case_when 8192 rows: in_range: 1, nulls: 0        1.00    110.1±1.72µs        ? ?/sec    1.01    111.1±2.79µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 20 entries, all equally true/case_when 8192 rows: in_range: 0.1, nulls: 0           1.00    117.2±1.28µs        ? ?/sec    1.01    118.3±1.69µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 20 entries, all equally true/case_when 8192 rows: in_range: 0.1, nulls: 0.1         1.00    132.3±0.49µs        ? ?/sec    1.02    135.0±7.14µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 20 entries, all equally true/case_when 8192 rows: in_range: 0.1, nulls: 0.5         1.00    146.1±0.89µs        ? ?/sec    1.00    146.6±1.18µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 20 entries, all equally true/case_when 8192 rows: in_range: 0.5, nulls: 0           1.00    117.8±2.15µs        ? ?/sec    1.00    118.2±1.70µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 20 entries, all equally true/case_when 8192 rows: in_range: 0.5, nulls: 0.1         1.00    132.5±1.40µs        ? ?/sec    1.01    133.4±1.37µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 20 entries, all equally true/case_when 8192 rows: in_range: 0.5, nulls: 0.5         1.00    146.6±3.04µs        ? ?/sec    1.00    147.1±1.52µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 20 entries, all equally true/case_when 8192 rows: in_range: 0.9, nulls: 0           1.00    117.2±1.22µs        ? ?/sec    1.01    118.1±1.41µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 20 entries, all equally true/case_when 8192 rows: in_range: 0.9, nulls: 0.1         1.00    132.4±1.48µs        ? ?/sec    1.01    133.5±1.37µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 20 entries, all equally true/case_when 8192 rows: in_range: 1, nulls: 0             1.00    117.2±1.28µs        ? ?/sec    1.01    118.2±2.09µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 20 entries, only first 2 are true/case_when 8192 rows: in_range: 0.1, nulls: 0      1.00    110.3±1.36µs        ? ?/sec    1.00    109.9±1.02µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 20 entries, only first 2 are true/case_when 8192 rows: in_range: 0.1, nulls: 0.1    1.00    120.0±0.88µs        ? ?/sec    1.01    120.7±1.72µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 20 entries, only first 2 are true/case_when 8192 rows: in_range: 0.1, nulls: 0.5    1.00    120.9±0.65µs        ? ?/sec    1.00    121.0±1.95µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 20 entries, only first 2 are true/case_when 8192 rows: in_range: 0.5, nulls: 0      1.00    110.0±1.86µs        ? ?/sec    1.01    111.0±2.43µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 20 entries, only first 2 are true/case_when 8192 rows: in_range: 0.5, nulls: 0.1    1.00    119.7±1.03µs        ? ?/sec    1.01    120.8±1.48µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 20 entries, only first 2 are true/case_when 8192 rows: in_range: 0.5, nulls: 0.5    1.00    120.6±0.46µs        ? ?/sec    1.00    120.4±1.19µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 20 entries, only first 2 are true/case_when 8192 rows: in_range: 0.9, nulls: 0      1.00    109.4±0.99µs        ? ?/sec    1.01    110.8±2.12µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 20 entries, only first 2 are true/case_when 8192 rows: in_range: 0.9, nulls: 0.1    1.00    119.9±0.90µs        ? ?/sec    1.01    120.6±1.39µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 20 entries, only first 2 are true/case_when 8192 rows: in_range: 1, nulls: 0        1.00    110.5±1.87µs        ? ?/sec    1.00    110.5±1.40µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 5 entries, all equally true/case_when 8192 rows: in_range: 0.1, nulls: 0            1.00    118.0±1.48µs        ? ?/sec    1.01    118.6±0.91µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 5 entries, all equally true/case_when 8192 rows: in_range: 0.1, nulls: 0.1          1.00    130.2±0.58µs        ? ?/sec    1.01    132.1±2.36µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 5 entries, all equally true/case_when 8192 rows: in_range: 0.1, nulls: 0.5          1.00    129.7±1.51µs        ? ?/sec    1.00    129.4±0.78µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 5 entries, all equally true/case_when 8192 rows: in_range: 0.5, nulls: 0            1.00    117.8±1.41µs        ? ?/sec    1.01    118.5±0.66µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 5 entries, all equally true/case_when 8192 rows: in_range: 0.5, nulls: 0.1          1.00    130.3±0.43µs        ? ?/sec    1.02    132.3±7.68µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 5 entries, all equally true/case_when 8192 rows: in_range: 0.5, nulls: 0.5          1.00    130.0±2.10µs        ? ?/sec    1.00    129.6±1.68µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 5 entries, all equally true/case_when 8192 rows: in_range: 0.9, nulls: 0            1.00    117.9±1.78µs        ? ?/sec    1.01    118.6±1.37µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 5 entries, all equally true/case_when 8192 rows: in_range: 0.9, nulls: 0.1          1.00    130.4±1.72µs        ? ?/sec    1.01    131.2±1.36µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 5 entries, all equally true/case_when 8192 rows: in_range: 1, nulls: 0              1.00    117.8±1.35µs        ? ?/sec    1.01    118.7±1.16µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 5 entries, only first 2 are true/case_when 8192 rows: in_range: 0.1, nulls: 0       1.00    110.0±2.09µs        ? ?/sec    1.00    110.5±1.52µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 5 entries, only first 2 are true/case_when 8192 rows: in_range: 0.1, nulls: 0.1     1.00    119.8±0.82µs        ? ?/sec    1.00    120.4±1.16µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 5 entries, only first 2 are true/case_when 8192 rows: in_range: 0.1, nulls: 0.5     1.00    120.9±1.79µs        ? ?/sec    1.00    120.5±0.99µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 5 entries, only first 2 are true/case_when 8192 rows: in_range: 0.5, nulls: 0       1.00    110.2±3.15µs        ? ?/sec    1.00    110.6±1.87µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 5 entries, only first 2 are true/case_when 8192 rows: in_range: 0.5, nulls: 0.1     1.00    120.2±5.03µs        ? ?/sec    1.00    120.6±0.99µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 5 entries, only first 2 are true/case_when 8192 rows: in_range: 0.5, nulls: 0.5     1.00    120.8±0.63µs        ? ?/sec    1.00    120.4±0.93µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 5 entries, only first 2 are true/case_when 8192 rows: in_range: 0.9, nulls: 0       1.00    110.6±2.11µs        ? ?/sec    1.00    111.0±2.41µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 5 entries, only first 2 are true/case_when 8192 rows: in_range: 0.9, nulls: 0.1     1.00    119.7±0.68µs        ? ?/sec    1.01    121.0±2.73µs        ? ?/sec
lookup_table_case_when/case when i32 -> utf8, 5 entries, only first 2 are true/case_when 8192 rows: in_range: 1, nulls: 0         1.00    110.1±1.49µs        ? ?/sec    1.01    111.4±2.07µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 10 entries, all equally true/case_when 8192 rows: in_range: 0.1, nulls: 0           1.00    142.2±3.43µs        ? ?/sec    1.02    145.8±3.74µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 10 entries, all equally true/case_when 8192 rows: in_range: 0.1, nulls: 0.1         1.00    148.2±3.79µs        ? ?/sec    1.02    151.2±4.45µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 10 entries, all equally true/case_when 8192 rows: in_range: 0.1, nulls: 0.5         1.00    133.9±1.82µs        ? ?/sec    1.03    137.3±2.04µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 10 entries, all equally true/case_when 8192 rows: in_range: 0.5, nulls: 0           1.00    143.6±4.14µs        ? ?/sec    1.02    146.1±3.10µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 10 entries, all equally true/case_when 8192 rows: in_range: 0.5, nulls: 0.1         1.00    147.7±2.65µs        ? ?/sec    1.02    151.1±4.09µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 10 entries, all equally true/case_when 8192 rows: in_range: 0.5, nulls: 0.5         1.00    133.4±0.63µs        ? ?/sec    1.03    136.8±1.80µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 10 entries, all equally true/case_when 8192 rows: in_range: 0.9, nulls: 0           1.00    141.7±2.68µs        ? ?/sec    1.03    146.3±4.19µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 10 entries, all equally true/case_when 8192 rows: in_range: 0.9, nulls: 0.1         1.04    156.1±3.04µs        ? ?/sec    1.00    150.7±3.62µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 10 entries, all equally true/case_when 8192 rows: in_range: 1, nulls: 0             1.00    142.0±4.51µs        ? ?/sec    1.03    145.6±3.68µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 10 entries, only first 2 are true/case_when 8192 rows: in_range: 0.1, nulls: 0      1.00    134.5±1.34µs        ? ?/sec    1.00    135.1±1.13µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 10 entries, only first 2 are true/case_when 8192 rows: in_range: 0.1, nulls: 0.1    1.00    138.4±0.86µs        ? ?/sec    1.02    140.5±4.07µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 10 entries, only first 2 are true/case_when 8192 rows: in_range: 0.1, nulls: 0.5    1.00    129.5±0.45µs        ? ?/sec    1.03    133.9±1.28µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 10 entries, only first 2 are true/case_when 8192 rows: in_range: 0.5, nulls: 0      1.00    134.3±0.98µs        ? ?/sec    1.03    138.0±2.61µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 10 entries, only first 2 are true/case_when 8192 rows: in_range: 0.5, nulls: 0.1    1.00    139.8±2.35µs        ? ?/sec    1.02    143.1±2.54µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 10 entries, only first 2 are true/case_when 8192 rows: in_range: 0.5, nulls: 0.5    1.00    130.0±0.93µs        ? ?/sec    1.03    134.0±1.38µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 10 entries, only first 2 are true/case_when 8192 rows: in_range: 0.9, nulls: 0      1.00    136.0±2.64µs        ? ?/sec    1.00    136.4±2.09µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 10 entries, only first 2 are true/case_when 8192 rows: in_range: 0.9, nulls: 0.1    1.00    141.1±4.63µs        ? ?/sec    1.00    140.4±2.02µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 10 entries, only first 2 are true/case_when 8192 rows: in_range: 1, nulls: 0        1.00    134.5±1.55µs        ? ?/sec    1.02    137.3±4.43µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 20 entries, all equally true/case_when 8192 rows: in_range: 0.1, nulls: 0           1.01    144.9±8.19µs        ? ?/sec    1.00    144.1±3.52µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 20 entries, all equally true/case_when 8192 rows: in_range: 0.1, nulls: 0.1         1.00    146.3±2.18µs        ? ?/sec    1.01    147.9±2.76µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 20 entries, all equally true/case_when 8192 rows: in_range: 0.1, nulls: 0.5         1.00    133.5±2.07µs        ? ?/sec    1.03    137.5±2.86µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 20 entries, all equally true/case_when 8192 rows: in_range: 0.5, nulls: 0           1.00    143.2±3.98µs        ? ?/sec    1.01    144.9±3.28µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 20 entries, all equally true/case_when 8192 rows: in_range: 0.5, nulls: 0.1         1.01    149.5±5.41µs        ? ?/sec    1.00    148.0±2.68µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 20 entries, all equally true/case_when 8192 rows: in_range: 0.5, nulls: 0.5         1.00    132.1±1.33µs        ? ?/sec    1.03    135.8±1.25µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 20 entries, all equally true/case_when 8192 rows: in_range: 0.9, nulls: 0           1.00    142.9±6.41µs        ? ?/sec    1.01    145.1±2.50µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 20 entries, all equally true/case_when 8192 rows: in_range: 0.9, nulls: 0.1         1.00    146.2±4.27µs        ? ?/sec    1.01    147.4±2.94µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 20 entries, all equally true/case_when 8192 rows: in_range: 1, nulls: 0             1.00    142.7±2.78µs        ? ?/sec    1.01    144.3±2.88µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 20 entries, only first 2 are true/case_when 8192 rows: in_range: 0.1, nulls: 0      1.00    134.8±0.88µs        ? ?/sec    1.01    136.7±7.70µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 20 entries, only first 2 are true/case_when 8192 rows: in_range: 0.1, nulls: 0.1    1.00    138.6±2.97µs        ? ?/sec    1.02    140.9±1.24µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 20 entries, only first 2 are true/case_when 8192 rows: in_range: 0.1, nulls: 0.5    1.00    130.6±0.60µs        ? ?/sec    1.03    133.9±0.74µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 20 entries, only first 2 are true/case_when 8192 rows: in_range: 0.5, nulls: 0      1.00    134.2±0.64µs        ? ?/sec    1.03    138.3±2.55µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 20 entries, only first 2 are true/case_when 8192 rows: in_range: 0.5, nulls: 0.1    1.00    139.1±1.07µs        ? ?/sec    1.01    140.9±1.02µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 20 entries, only first 2 are true/case_when 8192 rows: in_range: 0.5, nulls: 0.5    1.02    135.3±3.90µs        ? ?/sec    1.00    133.1±0.44µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 20 entries, only first 2 are true/case_when 8192 rows: in_range: 0.9, nulls: 0      1.00    134.1±1.08µs        ? ?/sec    1.01    135.7±2.39µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 20 entries, only first 2 are true/case_when 8192 rows: in_range: 0.9, nulls: 0.1    1.00    139.5±2.36µs        ? ?/sec    1.00    139.9±0.66µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 20 entries, only first 2 are true/case_when 8192 rows: in_range: 1, nulls: 0        1.00    134.9±1.93µs        ? ?/sec    1.01    136.4±1.24µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 5 entries, all equally true/case_when 8192 rows: in_range: 0.1, nulls: 0            1.00    143.4±0.86µs        ? ?/sec    1.02    146.3±4.44µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 5 entries, all equally true/case_when 8192 rows: in_range: 0.1, nulls: 0.1          1.00    146.8±0.75µs        ? ?/sec    1.02    149.1±0.60µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 5 entries, all equally true/case_when 8192 rows: in_range: 0.1, nulls: 0.5          1.00    133.5±1.36µs        ? ?/sec    1.03    137.7±1.45µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 5 entries, all equally true/case_when 8192 rows: in_range: 0.5, nulls: 0            1.00    143.3±2.82µs        ? ?/sec    1.02    146.0±3.10µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 5 entries, all equally true/case_when 8192 rows: in_range: 0.5, nulls: 0.1          1.00    148.8±4.48µs        ? ?/sec    1.02    151.7±4.19µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 5 entries, all equally true/case_when 8192 rows: in_range: 0.5, nulls: 0.5          1.00    134.1±1.83µs        ? ?/sec    1.03    137.6±1.62µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 5 entries, all equally true/case_when 8192 rows: in_range: 0.9, nulls: 0            1.00    143.1±1.05µs        ? ?/sec    1.03    146.9±3.49µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 5 entries, all equally true/case_when 8192 rows: in_range: 0.9, nulls: 0.1          1.00    146.5±0.97µs        ? ?/sec    1.02    149.7±3.11µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 5 entries, all equally true/case_when 8192 rows: in_range: 1, nulls: 0              1.00    143.2±1.12µs        ? ?/sec    1.02    146.5±5.23µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 5 entries, only first 2 are true/case_when 8192 rows: in_range: 0.1, nulls: 0       1.00    134.7±0.93µs        ? ?/sec    1.01    135.8±2.35µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 5 entries, only first 2 are true/case_when 8192 rows: in_range: 0.1, nulls: 0.1     1.00    138.6±1.00µs        ? ?/sec    1.01    140.5±2.30µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 5 entries, only first 2 are true/case_when 8192 rows: in_range: 0.1, nulls: 0.5     1.00    129.5±0.91µs        ? ?/sec    1.03    133.9±2.15µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 5 entries, only first 2 are true/case_when 8192 rows: in_range: 0.5, nulls: 0       1.00    134.3±1.09µs        ? ?/sec    1.05    141.1±5.09µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 5 entries, only first 2 are true/case_when 8192 rows: in_range: 0.5, nulls: 0.1     1.00    139.7±2.08µs        ? ?/sec    1.01    141.3±1.40µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 5 entries, only first 2 are true/case_when 8192 rows: in_range: 0.5, nulls: 0.5     1.00    130.1±0.74µs        ? ?/sec    1.02    133.2±0.79µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 5 entries, only first 2 are true/case_when 8192 rows: in_range: 0.9, nulls: 0       1.00    134.5±1.77µs        ? ?/sec    1.01    135.6±1.20µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 5 entries, only first 2 are true/case_when 8192 rows: in_range: 0.9, nulls: 0.1     1.00    140.3±4.13µs        ? ?/sec    1.00    140.5±3.45µs        ? ?/sec
lookup_table_case_when/case when utf8 -> i32, 5 entries, only first 2 are true/case_when 8192 rows: in_range: 1, nulls: 0         1.00    134.7±2.20µs        ? ?/sec    1.01    135.5±0.83µs        ? ?/sec

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

Labels

physical-expr Changes to the physical-expr crates

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Potential optimization for CASE WHEN for protecting against divide by zero

5 participants