Skip to content

feat: optimize CASE WHEN for divide-by-zero protection pattern#19994

Open
CuteChuanChuan wants to merge 6 commits intoapache:mainfrom
CuteChuanChuan:raymond/11570-optimize-case-when
Open

feat: optimize CASE WHEN for divide-by-zero protection pattern#19994
CuteChuanChuan wants to merge 6 commits intoapache:mainfrom
CuteChuanChuan:raymond/11570-optimize-case-when

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.

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,

I think the performance gap might come from execution model differences. Please correct me if I am wrong.

ExprOrExpr: evaluate condition → build selection → execute on selected rows → merge
DivideByZeroProtection: fully vectorized Arrow kernels

The vectorized path avoids selection/branching overhead, which is why it wins when most rows need computation (low zero density). However, ExprOrExpr's short-circuit helps when many rows are filtered (high zero density).

Although I don't have concrete ideas about potential ExprOrExpr improvements for this pattern yet, I'd be happy to explore further if you have any suggestions!

Copy link
Contributor

Choose a reason for hiding this comment

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

I've been studying the results a bit. I'll add some extra comments on the relevant bits of code.

Copy link
Contributor

Choose a reason for hiding this comment

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

There is another PR here from @pepijnve to improve some cases

@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

@pepijnve
Copy link
Contributor

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, 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, 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, 90% zeros: DivideByZeroProtection                                                            1.00     44.7±0.38µs        ? ?/sec    1.82     81.5±2.96µs        ? ?/sec

Interesting results. Significantly faster when there are no zeroes, but as the percentage increases the balance tips and 90% zeroes is actually quite a bit slower.

use arrow::compute::kernels::numeric::div;

let zero = ScalarValue::new_zero(divisor.data_type())?.to_scalar()?;
let zero_mask = eq(divisor, &zero)?;
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you need to make sure you use the condition from the when expression here in order to get the correct result. I added these SLTs and they were not all passing.

query I
SELECT CASE WHEN d != 0 THEN n / d ELSE NULL END FROM (VALUES (1, 1), (1, 0), (1, -1)) t(n,d)
----
1
NULL
-1

query I
SELECT CASE WHEN d > 0 THEN n / d ELSE NULL END FROM (VALUES (1, 1), (1, 0), (1, -1)) t(n,d)
----
1
NULL
NULL

query I
SELECT CASE WHEN d < 0 THEN n / d ELSE NULL END FROM (VALUES (1, 1), (1, 0), (1, -1)) t(n,d)
----
NULL
NULL
-1

@pepijnve
Copy link
Contributor

pepijnve commented Feb 1, 2026

In the microbenchmark, I think it might be preferable to use != 0 rather than > 0. With > 0, even for the '0% zeroes' benchmark, ~50% of the values are negative and do not match the condition. The benchmark name suggests we're taking the branch 0% of the time, while in fact it's 50% which is a bit misleading. Due to an implementation issue (see comment on safe_divide_arrays) we're also not comparing the same thing entirely.

I had a closer look at what was going on in what I thought was the expr_or_expr implementation, but it turns out that wasn't actually being used. Instead the general no_expr implementation was being used. This was due to the else branch being literal null. I tinkered a bit with the existing code to make sure expr_or_expr is actually used, and that brings the results much closer, to the point where I'm wondering if the divide-by-zero special case is still worth it.

The changes I made for expr_or_expr are general improvements, so I'll make a separate PR with those.

divide_by_zero_protection/8192 rows, 0% zeros: DivideByZeroProtection
                        time:   [8.0014 µs 8.0112 µs 8.0208 µs]
divide_by_zero_protection/8192 rows, 0% zeros: ExpressionOrExpression
                        time:   [6.6199 µs 6.6250 µs 6.6300 µs]

Here the expr_or_expr implementation just returns the evaluation of the then expression with minimal overhead. Skipping zip and nullif is probably what makes the difference here.

divide_by_zero_protection/8192 rows, 10% zeros: DivideByZeroProtection
                        time:   [17.586 µs 17.641 µs 17.699 µs]
divide_by_zero_protection/8192 rows, 10% zeros: ExpressionOrExpression
                        time:   [32.909 µs 32.965 µs 33.030 µs]

Here expr_or_expr has to filter the record batch and needs to copy 90% of the data. In the profiler this is where most of the time is spent.

divide_by_zero_protection/8192 rows, 50% zeros: DivideByZeroProtection
                        time:   [53.277 µs 53.440 µs 53.601 µs]
divide_by_zero_protection/8192 rows, 50% zeros: ExpressionOrExpression
                        time:   [49.745 µs 49.997 µs 50.309 µs]

divide_by_zero_protection/8192 rows, 90% zeros: DivideByZeroProtection
                        time:   [54.223 µs 54.287 µs 54.359 µs]
divide_by_zero_protection/8192 rows, 90% zeros: ExpressionOrExpression
                        time:   [16.432 µs 16.500 µs 16.570 µs]

From 50% on it looks like the number of divisions starts to outweigh the filtering work. Copying half the data to then only perform half the number of divisions ends up being beneficial. That would also explain the 90% results since you're doing much fewer divisions then.

@CuteChuanChuan
Copy link
Contributor Author

CuteChuanChuan commented Feb 1, 2026

Due to an implementation issue (see comment on safe_divide_arrays) we're also not comparing the same thing entirely.

I tinkered a bit with the existing code to make sure expr_or_expr is actually used, and that brings the results much closer, to the point where I'm wondering if the divide-by-zero special case is still worth it.

The changes I made for expr_or_expr are general improvements, so I'll make a separate PR with those.

@pepijnve
Thanks for the detailed analysis and pointing out the bug in my code! I see the issue now - I should use the condition in the when clause, but the implementation only handles the d != 0 case correctly. I'll wait for your expr_or_expr improvements PR. Once that's merged, we can re-evaluate whether this optimization is still beneficial. If the gap is minimal, I'm happy to close this PR.

@alamb
Copy link
Contributor

alamb commented Feb 2, 2026

@alamb
Copy link
Contributor

alamb commented Feb 2, 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 (328d8b1) to d28a03c 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
Copy link
Contributor

alamb commented Feb 2, 2026

running with updated benchmarks

@alamb
Copy link
Contributor

alamb commented Feb 2, 2026

run benchmark case_when

@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.01    126.1±1.96µs        ? ?/sec    1.00    125.2±1.35µs        ? ?/sec
case_when 8192x100: CASE WHEN c1 <= 500 THEN 1 ELSE 0 END                                                                         1.00     14.8±0.27µs        ? ?/sec    1.00     14.8±0.11µs        ? ?/sec
case_when 8192x100: CASE WHEN c1 <= 500 THEN c2 ELSE c3 END                                                                       1.00     17.6±0.52µs        ? ?/sec    1.01     17.7±0.44µs        ? ?/sec
case_when 8192x100: CASE WHEN c1 <= 500 THEN c2 [ELSE NULL] END                                                                   1.01      6.5±0.02µs        ? ?/sec    1.00      6.4±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.02     48.9±0.40ms        ? ?/sec    1.00     48.0±0.55ms        ? ?/sec
case_when 8192x100: CASE c1 WHEN 0 THEN 0 WHEN 1 THEN 1 ... WHEN n THEN n ELSE n + 1 END                                          1.00     40.5±0.24µs        ? ?/sec    1.02     41.5±0.66µs        ? ?/sec
case_when 8192x100: CASE c1 WHEN 1 THEN c2 WHEN 2 THEN c3 END                                                                     1.01     29.8±0.81µs        ? ?/sec    1.00     29.5±0.86µ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     37.6±0.66µs        ? ?/sec    1.01     37.8±0.70µ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.9±1.46µs        ? ?/sec    1.00    125.6±1.33µs        ? ?/sec
case_when 8192x3: CASE WHEN c1 <= 500 THEN 1 ELSE 0 END                                                                           1.00     14.7±0.14µs        ? ?/sec    1.01     14.8±0.43µs        ? ?/sec
case_when 8192x3: CASE WHEN c1 <= 500 THEN c2 ELSE c3 END                                                                         1.00     17.3±0.51µs        ? ?/sec    1.01     17.4±0.46µs        ? ?/sec
case_when 8192x3: CASE WHEN c1 <= 500 THEN c2 [ELSE NULL] END                                                                     1.02      6.5±0.08µs        ? ?/sec    1.00      6.4±0.11µ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.2±0.45ms        ? ?/sec    1.02     49.1±1.29ms        ? ?/sec
case_when 8192x3: CASE c1 WHEN 0 THEN 0 WHEN 1 THEN 1 ... WHEN n THEN n ELSE n + 1 END                                            1.00     40.2±0.41µs        ? ?/sec    1.03     41.6±0.22µs        ? ?/sec
case_when 8192x3: CASE c1 WHEN 1 THEN c2 WHEN 2 THEN c3 END                                                                       1.00     29.5±0.73µs        ? ?/sec    1.02     30.1±0.70µ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     37.7±1.11µs        ? ?/sec    1.00     37.8±1.03µ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.20µs        ? ?/sec    1.00    125.3±1.64µs        ? ?/sec
case_when 8192x50: CASE WHEN c1 <= 500 THEN 1 ELSE 0 END                                                                          1.01     14.8±0.04µs        ? ?/sec    1.00     14.8±0.06µs        ? ?/sec
case_when 8192x50: CASE WHEN c1 <= 500 THEN c2 ELSE c3 END                                                                        1.00     17.4±0.63µs        ? ?/sec    1.01     17.5±0.49µs        ? ?/sec
case_when 8192x50: CASE WHEN c1 <= 500 THEN c2 [ELSE NULL] END                                                                    1.02      6.6±0.02µs        ? ?/sec    1.00      6.4±0.09µ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.02     49.0±0.91ms        ? ?/sec    1.00     48.1±1.06ms        ? ?/sec
case_when 8192x50: CASE c1 WHEN 0 THEN 0 WHEN 1 THEN 1 ... WHEN n THEN n ELSE n + 1 END                                           1.00     41.2±0.37µs        ? ?/sec    1.05     43.1±1.49µs        ? ?/sec
case_when 8192x50: CASE c1 WHEN 1 THEN c2 WHEN 2 THEN c3 END                                                                      1.01     29.8±0.94µs        ? ?/sec    1.00     29.6±0.70µ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     37.7±1.40µs        ? ?/sec    1.03     38.9±1.16µs        ? ?/sec
divide_by_zero_protection/8192 rows, 0% zeros: DivideByZeroProtection                                                             1.48     48.2±0.54µs        ? ?/sec    1.00     32.6±0.12µs        ? ?/sec
divide_by_zero_protection/8192 rows, 10% zeros: DivideByZeroProtection                                                            2.09     96.2±1.52µs        ? ?/sec    1.00     46.1±0.15µs        ? ?/sec
divide_by_zero_protection/8192 rows, 50% zeros: DivideByZeroProtection                                                            1.50    135.2±2.82µs        ? ?/sec    1.00     90.0±0.86µs        ? ?/sec
divide_by_zero_protection/8192 rows, 90% zeros: DivideByZeroProtection                                                            1.00     58.5±0.25µs        ? ?/sec    1.42     83.3±0.24µ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    107.6±2.73µs        ? ?/sec    1.01    109.1±3.36µ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    120.7±1.79µs        ? ?/sec    1.00    120.7±1.17µ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    124.0±3.42µs        ? ?/sec    1.02    126.1±1.31µ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    107.2±1.67µs        ? ?/sec    1.00    107.1±1.18µ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    120.6±1.88µs        ? ?/sec    1.00    121.0±1.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    123.6±1.89µs        ? ?/sec    1.02    125.9±1.97µ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    107.4±1.87µs        ? ?/sec    1.00    107.2±2.13µ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    120.6±1.55µs        ? ?/sec    1.00    120.7±0.50µ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.01    107.6±2.27µs        ? ?/sec    1.00    106.8±0.41µ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     97.7±0.65µs        ? ?/sec    1.02     99.6±1.96µ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    108.3±1.25µs        ? ?/sec    1.02    109.9±0.65µ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    109.3±1.29µs        ? ?/sec    1.03    112.6±0.66µ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     99.1±5.16µs        ? ?/sec    1.00     99.0±1.36µ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    108.6±1.22µs        ? ?/sec    1.01    110.0±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.5, nulls: 0.5    1.00    109.1±1.19µs        ? ?/sec    1.03    112.4±1.42µ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     98.1±1.30µs        ? ?/sec    1.01     99.3±2.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.9, nulls: 0.1    1.00    108.2±1.00µs        ? ?/sec    1.02    110.3±3.64µ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     98.6±2.07µs        ? ?/sec    1.01     99.3±1.94µ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.02    108.5±3.65µs        ? ?/sec    1.00    106.8±1.50µ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    121.2±2.75µs        ? ?/sec    1.00    121.1±2.18µ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    133.7±2.61µs        ? ?/sec    1.01    134.7±2.07µ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    108.3±2.70µs        ? ?/sec    1.00    107.0±1.56µ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    121.3±2.83µs        ? ?/sec    1.01    122.0±2.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.5         1.00    133.3±2.29µs        ? ?/sec    1.01    134.9±1.55µ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    107.9±2.74µs        ? ?/sec    1.00    107.2±3.42µ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.01    121.8±4.18µs        ? ?/sec    1.00    120.8±1.35µ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.02    108.5±3.42µs        ? ?/sec    1.00    106.7±2.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.1, nulls: 0      1.00     98.1±1.33µs        ? ?/sec    1.01     99.3±2.08µ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    110.4±9.36µs        ? ?/sec    1.00    110.3±1.92µ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    109.7±1.86µs        ? ?/sec    1.03    112.7±1.38µ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     98.7±3.11µs        ? ?/sec    1.00     98.8±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.5, nulls: 0.1    1.00    108.6±2.03µs        ? ?/sec    1.01    109.7±0.98µ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    109.3±1.96µs        ? ?/sec    1.03    112.3±0.85µ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     98.1±1.90µs        ? ?/sec    1.01     98.8±1.90µ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    108.4±0.69µs        ? ?/sec    1.01    109.9±1.55µ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     98.0±1.34µs        ? ?/sec    1.01     99.0±2.04µ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    107.1±2.34µs        ? ?/sec    1.01    108.3±2.28µ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    118.0±0.45µs        ? ?/sec    1.01    119.1±0.58µ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    116.5±0.89µs        ? ?/sec    1.03    120.3±0.91µ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    106.5±0.71µs        ? ?/sec    1.01    107.5±0.94µ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    118.2±1.01µs        ? ?/sec    1.01    119.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.5, nulls: 0.5          1.00    116.6±0.65µs        ? ?/sec    1.03    120.5±0.87µ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    106.7±1.85µs        ? ?/sec    1.01    107.5±1.17µ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    118.1±0.75µs        ? ?/sec    1.01    119.5±3.57µ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    106.5±0.67µs        ? ?/sec    1.01    107.2±0.92µ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     97.8±0.88µs        ? ?/sec    1.02     99.5±1.33µ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    108.3±1.17µs        ? ?/sec    1.02    110.1±1.34µ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    109.6±2.17µs        ? ?/sec    1.03    113.0±1.46µ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     99.0±2.17µs        ? ?/sec    1.00     99.2±1.78µ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    108.6±2.02µs        ? ?/sec    1.01    109.9±1.55µ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    109.4±1.77µs        ? ?/sec    1.03    112.3±1.34µ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     98.3±1.73µs        ? ?/sec    1.01     99.1±1.64µ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    108.3±1.48µs        ? ?/sec    1.01    109.7±0.90µ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     98.4±2.03µs        ? ?/sec    1.01     99.5±2.02µ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    141.6±3.24µs        ? ?/sec    1.01    143.6±2.83µ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.1±2.70µs        ? ?/sec    1.01    149.0±3.17µ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    135.3±0.93µs        ? ?/sec    1.06    143.2±2.76µ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    141.2±2.76µs        ? ?/sec    1.02    143.7±3.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.1         1.00    148.8±2.78µs        ? ?/sec    1.00    148.3±3.27µ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.01    136.3±1.56µs        ? ?/sec    1.00    135.3±1.74µ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    140.7±1.56µs        ? ?/sec    1.02    143.3±2.83µ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    147.9±2.66µs        ? ?/sec    1.00    148.3±2.50µ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    141.6±3.68µs        ? ?/sec    1.01    143.3±2.87µ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.9±4.79µs        ? ?/sec    1.00    136.2±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.1, nulls: 0.1    1.00    142.7±4.97µs        ? ?/sec    1.01    143.7±5.23µ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.01    132.4±1.67µs        ? ?/sec    1.00    131.1±1.31µ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    132.7±0.86µs        ? ?/sec    1.03    136.5±1.03µ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    138.8±0.93µs        ? ?/sec    1.01    140.1±1.60µ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.01    133.0±2.15µs        ? ?/sec    1.00    132.2±1.31µ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    133.4±0.98µs        ? ?/sec    1.04    138.2±9.64µ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.01    142.1±6.99µs        ? ?/sec    1.00    141.0±5.25µ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.3±1.86µs        ? ?/sec    1.02    136.4±1.49µ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    143.9±4.30µs        ? ?/sec    1.00    143.3±3.44µ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.02    150.8±3.36µs        ? ?/sec    1.00    148.1±3.41µ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    134.6±1.52µs        ? ?/sec    1.00    135.2±2.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.00    142.2±3.24µs        ? ?/sec    1.00    142.3±0.99µ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    147.7±8.27µs        ? ?/sec    1.00    146.0±3.06µ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.02    136.9±2.25µs        ? ?/sec    1.00    133.8±1.49µ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    141.8±5.74µs        ? ?/sec    1.01    143.6±3.01µ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.01    146.5±2.48µs        ? ?/sec    1.00    145.6±1.75µ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.2±3.36µs        ? ?/sec    1.01    143.0±3.16µ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    132.6±0.89µs        ? ?/sec    1.04    137.3±3.50µ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.01   142.1±11.99µs        ? ?/sec    1.00    141.2±4.82µ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    132.4±1.59µs        ? ?/sec    1.00    132.8±1.83µ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    132.8±0.91µs        ? ?/sec    1.03    136.4±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.1    1.00    140.8±4.82µs        ? ?/sec    1.00    140.3±2.73µ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.01    132.7±3.12µs        ? ?/sec    1.00    131.3±1.03µ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±1.77µs        ? ?/sec    1.01    135.3±1.85µ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.01    140.5±1.41µs        ? ?/sec    1.00    139.3±0.98µ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.4±1.65µs        ? ?/sec    1.02    137.2±2.76µ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    144.0±5.57µs        ? ?/sec    1.02    146.3±5.77µ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    148.3±2.65µs        ? ?/sec    1.00    148.0±2.80µ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    136.3±2.37µs        ? ?/sec    1.00    136.0±2.52µ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    145.0±5.48µs        ? ?/sec    1.06    153.0±6.97µ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    147.8±0.82µs        ? ?/sec    1.01    148.9±3.74µ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    136.1±2.17µs        ? ?/sec    1.00    135.9±2.78µ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.6±3.56µs        ? ?/sec    1.02    145.3±1.43µ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    148.4±3.15µs        ? ?/sec    1.00    148.2±1.83µ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    144.7±5.35µs        ? ?/sec    1.01    145.6±3.34µ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    136.6±4.61µs        ? ?/sec    1.00    136.7±2.58µ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.1±1.71µs        ? ?/sec    1.00    139.6±0.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.1, nulls: 0.5     1.00    131.8±0.60µs        ? ?/sec    1.00    132.3±1.77µ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±2.65µs        ? ?/sec    1.02    136.6±2.25µ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    138.7±0.83µs        ? ?/sec    1.01    140.1±1.17µ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    132.1±0.82µs        ? ?/sec    1.00    132.2±1.56µ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    132.8±0.67µs        ? ?/sec    1.02    135.9±5.34µ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    138.8±1.48µs        ? ?/sec    1.00    139.3±0.86µ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.0±0.90µs        ? ?/sec    1.01    135.3±0.89µ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 (328d8b1) to d28a03c 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.4±1.60µs        ? ?/sec    1.00    125.2±2.00µs        ? ?/sec
case_when 8192x100: CASE WHEN c1 <= 500 THEN 1 ELSE 0 END                                                                         1.00     14.8±0.36µs        ? ?/sec    1.00     14.8±0.18µs        ? ?/sec
case_when 8192x100: CASE WHEN c1 <= 500 THEN c2 ELSE c3 END                                                                       1.01     17.7±0.59µs        ? ?/sec    1.00     17.5±0.53µs        ? ?/sec
case_when 8192x100: CASE WHEN c1 <= 500 THEN c2 [ELSE NULL] END                                                                   1.00      6.5±0.05µs        ? ?/sec    1.01      6.5±0.09µ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.01     47.9±0.40ms        ? ?/sec    1.00     47.6±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.03     43.0±0.42µs        ? ?/sec    1.00     41.8±0.46µs        ? ?/sec
case_when 8192x100: CASE c1 WHEN 1 THEN c2 WHEN 2 THEN c3 END                                                                     1.03     30.3±0.76µs        ? ?/sec    1.00     29.3±0.84µ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.03     38.7±0.50µs        ? ?/sec    1.00     37.4±0.54µ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.6±1.85µs        ? ?/sec    1.00    125.2±1.28µs        ? ?/sec
case_when 8192x3: CASE WHEN c1 <= 500 THEN 1 ELSE 0 END                                                                           1.00     14.7±0.07µs        ? ?/sec    1.00     14.7±0.11µs        ? ?/sec
case_when 8192x3: CASE WHEN c1 <= 500 THEN c2 ELSE c3 END                                                                         1.00     17.2±0.63µs        ? ?/sec    1.00     17.2±1.11µs        ? ?/sec
case_when 8192x3: CASE WHEN c1 <= 500 THEN c2 [ELSE NULL] END                                                                     1.00      6.5±0.08µs        ? ?/sec    1.00      6.5±0.04µ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.01     48.1±0.75ms        ? ?/sec    1.00     47.7±0.61ms        ? ?/sec
case_when 8192x3: CASE c1 WHEN 0 THEN 0 WHEN 1 THEN 1 ... WHEN n THEN n ELSE n + 1 END                                            1.02     43.3±0.32µs        ? ?/sec    1.00     42.2±0.68µs        ? ?/sec
case_when 8192x3: CASE c1 WHEN 1 THEN c2 WHEN 2 THEN c3 END                                                                       1.00     29.6±0.68µs        ? ?/sec    1.03     30.4±0.71µ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     37.6±0.58µs        ? ?/sec    1.00     37.7±0.70µ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.7±4.70µs        ? ?/sec    1.00    125.2±1.74µs        ? ?/sec
case_when 8192x50: CASE WHEN c1 <= 500 THEN 1 ELSE 0 END                                                                          1.01     14.9±0.17µs        ? ?/sec    1.00     14.8±0.15µs        ? ?/sec
case_when 8192x50: CASE WHEN c1 <= 500 THEN c2 ELSE c3 END                                                                        1.01     17.5±0.49µs        ? ?/sec    1.00     17.3±0.42µs        ? ?/sec
case_when 8192x50: CASE WHEN c1 <= 500 THEN c2 [ELSE NULL] END                                                                    1.00      6.5±0.05µs        ? ?/sec    1.00      6.5±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     47.8±0.39ms        ? ?/sec    1.00     47.7±0.41ms        ? ?/sec
case_when 8192x50: CASE c1 WHEN 0 THEN 0 WHEN 1 THEN 1 ... WHEN n THEN n ELSE n + 1 END                                           1.01     43.2±0.50µs        ? ?/sec    1.00     42.9±0.29µs        ? ?/sec
case_when 8192x50: CASE c1 WHEN 1 THEN c2 WHEN 2 THEN c3 END                                                                      1.00     29.3±0.81µs        ? ?/sec    1.01     29.6±0.75µ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.3±0.85µs        ? ?/sec    1.01     38.7±0.59µs        ? ?/sec
divide_by_zero_protection/8192 rows, 0% zeros: DivideByZeroProtection                                                             1.47     48.2±0.46µs        ? ?/sec    1.00     32.8±0.23µs        ? ?/sec
divide_by_zero_protection/8192 rows, 10% zeros: DivideByZeroProtection                                                            2.08     95.6±1.22µs        ? ?/sec    1.00     46.1±0.50µs        ? ?/sec
divide_by_zero_protection/8192 rows, 50% zeros: DivideByZeroProtection                                                            1.51    134.8±2.85µs        ? ?/sec    1.00     89.3±0.57µs        ? ?/sec
divide_by_zero_protection/8192 rows, 90% zeros: DivideByZeroProtection                                                            1.00     58.5±0.43µs        ? ?/sec    1.42     83.3±0.54µ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    107.1±1.61µs        ? ?/sec    1.00    107.0±1.06µ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    119.8±0.47µs        ? ?/sec    1.01    121.1±0.74µ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    122.3±0.70µs        ? ?/sec    1.03    126.1±0.91µ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    105.7±0.41µs        ? ?/sec    1.01    107.0±1.62µ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    120.2±2.77µs        ? ?/sec    1.01    121.0±1.18µ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    122.4±1.20µs        ? ?/sec    1.04    126.8±1.70µ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    105.7±0.45µs        ? ?/sec    1.01    106.9±0.34µ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    120.1±1.91µs        ? ?/sec    1.01    120.8±0.51µ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    106.3±1.46µs        ? ?/sec    1.01    107.7±1.47µ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     98.2±1.53µs        ? ?/sec    1.02     99.7±3.53µ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    108.4±0.94µs        ? ?/sec    1.02    110.9±5.89µ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    109.1±0.56µs        ? ?/sec    1.03    112.1±1.31µ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     98.3±1.39µs        ? ?/sec    1.01     99.3±1.62µ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    108.6±1.27µs        ? ?/sec    1.02    111.0±4.86µ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    108.5±1.09µs        ? ?/sec    1.03    112.0±1.02µ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     98.7±1.69µs        ? ?/sec    1.00     98.7±2.10µ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    108.5±2.03µs        ? ?/sec    1.02    110.2±1.89µ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     98.7±2.04µs        ? ?/sec    1.01     99.2±2.35µ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    107.6±1.12µs        ? ?/sec    1.01    108.2±1.02µ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    120.6±1.47µs        ? ?/sec    1.01    121.2±1.00µ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    132.4±1.02µs        ? ?/sec    1.02    135.0±1.52µ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    107.6±1.68µs        ? ?/sec    1.01    108.2±0.77µ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    120.6±1.48µs        ? ?/sec    1.01    121.6±2.03µ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    132.4±1.46µs        ? ?/sec    1.02    134.8±0.88µ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    107.9±3.50µs        ? ?/sec    1.00    108.2±1.07µ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    120.1±1.09µs        ? ?/sec    1.01    121.2±1.27µ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    109.5±5.07µs        ? ?/sec    1.00    108.2±0.82µ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     97.7±0.72µs        ? ?/sec    1.01     99.0±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    108.4±0.88µs        ? ?/sec    1.02    110.6±3.79µ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    108.3±0.55µs        ? ?/sec    1.03    112.0±0.97µ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     98.9±1.26µs        ? ?/sec    1.01     99.9±5.63µ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    108.4±1.10µs        ? ?/sec    1.02    110.2±1.92µ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    108.5±0.80µs        ? ?/sec    1.03    112.2±0.91µ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     98.4±1.49µs        ? ?/sec    1.02     99.9±5.41µ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    108.8±1.67µs        ? ?/sec    1.01    109.9±0.78µ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     98.4±1.42µs        ? ?/sec    1.01     99.4±5.28µ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    106.3±1.46µs        ? ?/sec    1.01    107.5±0.53µ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    118.0±0.39µs        ? ?/sec    1.01    119.7±1.56µ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    116.2±0.72µs        ? ?/sec    1.03    120.0±1.38µ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    106.3±0.98µs        ? ?/sec    1.01    107.5±1.12µ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    118.7±2.34µs        ? ?/sec    1.01    119.6±1.67µ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    116.6±1.91µs        ? ?/sec    1.03    120.6±0.99µ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    106.3±1.21µs        ? ?/sec    1.01    107.4±0.62µ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    117.9±0.72µs        ? ?/sec    1.01    119.4±0.83µ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    106.1±1.08µs        ? ?/sec    1.01    107.3±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: 0.1, nulls: 0       1.00     97.9±0.98µs        ? ?/sec    1.01     98.6±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     1.00    108.7±1.08µs        ? ?/sec    1.01    109.9±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.1, nulls: 0.5     1.00    108.4±0.39µs        ? ?/sec    1.03    112.1±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.5, nulls: 0       1.00     98.1±1.63µs        ? ?/sec    1.03   101.3±11.57µ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    108.5±0.87µs        ? ?/sec    1.01    110.1±3.10µ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    108.5±1.26µs        ? ?/sec    1.03    112.1±1.15µ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     98.1±1.10µs        ? ?/sec    1.01     99.0±1.30µ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    109.1±2.77µs        ? ?/sec    1.01    109.9±1.13µ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     98.4±1.28µs        ? ?/sec    1.00     98.7±0.98µ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.7±4.13µs        ? ?/sec    1.01    143.6±2.92µ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    151.5±4.85µs        ? ?/sec    1.03    156.3±5.09µ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    135.9±1.75µs        ? ?/sec    1.00    135.3±0.76µ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    141.4±2.71µs        ? ?/sec    1.02    144.0±3.83µ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    148.1±2.28µs        ? ?/sec    1.00    147.4±1.60µ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    135.8±2.01µs        ? ?/sec    1.00    135.5±2.02µ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.4±3.18µs        ? ?/sec    1.03    145.1±4.61µ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    148.2±2.22µs        ? ?/sec    1.00    148.1±2.07µ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.3±3.22µs        ? ?/sec    1.01    143.8±2.50µ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.8±2.39µs        ? ?/sec    1.01    136.1±1.66µ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    139.5±0.98µs        ? ?/sec    1.00    139.7±1.86µ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    132.5±1.21µs        ? ?/sec    1.00    132.2±1.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      1.00    135.2±3.57µs        ? ?/sec    1.01    135.9±0.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.5, nulls: 0.1    1.01    140.1±2.26µs        ? ?/sec    1.00    138.6±0.85µ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    132.3±1.95µs        ? ?/sec    1.00    131.8±1.79µ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    132.7±0.46µs        ? ?/sec    1.01    134.4±0.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.9, nulls: 0.1    1.00    138.9±0.60µs        ? ?/sec    1.00    138.9±1.03µ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    132.9±1.28µs        ? ?/sec    1.02    135.4±2.18µ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    140.7±3.02µs        ? ?/sec    1.01    142.0±2.09µ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.0±3.31µs        ? ?/sec    1.00    145.9±2.83µ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    134.4±2.51µs        ? ?/sec    1.01    136.1±2.30µ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    141.2±2.68µs        ? ?/sec    1.01    142.5±1.85µ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    147.2±5.36µs        ? ?/sec    1.00    147.0±4.72µ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.01    134.5±1.62µs        ? ?/sec    1.00    133.5±1.27µ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    141.4±3.65µs        ? ?/sec    1.01    143.3±2.99µ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.1±1.66µs        ? ?/sec    1.00    146.5±2.63µ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.86µs        ? ?/sec    1.01    143.6±3.82µ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.2±1.67µs        ? ?/sec    1.01    135.4±1.52µ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.4±1.68µs        ? ?/sec    1.00    139.3±0.68µ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.01    132.6±2.23µs        ? ?/sec    1.00    131.7±1.08µ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    133.8±1.30µs        ? ?/sec    1.01    135.5±1.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.01    139.8±1.79µs        ? ?/sec    1.00    138.9±1.29µ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    133.5±1.75µs        ? ?/sec    1.00    131.3±0.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.9, nulls: 0      1.00    132.9±1.40µs        ? ?/sec    1.01    134.7±1.85µ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.4±1.41µs        ? ?/sec    1.00    139.2±1.56µ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    132.8±0.93µs        ? ?/sec    1.02    135.0±1.22µ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    142.2±3.92µs        ? ?/sec    1.02    145.6±2.68µ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    149.0±3.69µs        ? ?/sec    1.00    148.5±1.72µ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.9±1.98µs        ? ?/sec    1.01    136.8±2.02µ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.4±4.65µs        ? ?/sec    1.02    146.6±3.30µ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±2.62µs        ? ?/sec    1.00    148.1±1.89µ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    136.3±1.83µs        ? ?/sec    1.00    136.3±3.80µ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.0±3.06µs        ? ?/sec    1.10    156.2±4.86µ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.5±2.20µs        ? ?/sec    1.00    148.0±1.42µ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    142.2±2.89µs        ? ?/sec    1.02    145.0±2.28µ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    132.8±1.09µs        ? ?/sec    1.03    136.5±2.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.1, nulls: 0.1     1.00    139.0±0.49µs        ? ?/sec    1.00    139.0±0.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.1, nulls: 0.5     1.01    132.7±1.44µs        ? ?/sec    1.00    131.9±0.81µ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.9±2.49µs        ? ?/sec    1.04    139.8±6.26µ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.01    139.5±0.77µs        ? ?/sec    1.00    138.7±0.65µ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    131.9±0.74µs        ? ?/sec    1.00    131.8±0.97µ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    133.0±1.95µs        ? ?/sec    1.04    138.5±4.64µ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.4±0.80µs        ? ?/sec    1.00    139.0±1.12µ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    132.8±0.57µs        ? ?/sec    1.02    135.3±1.45µs        ? ?/sec

@alamb
Copy link
Contributor

alamb commented Feb 3, 2026

Divide by zero protection is looking pretty good:

divide_by_zero_protection/8192 rows, 0% zeros: DivideByZeroProtection                                                             1.47     48.2±0.46µs        ? ?/sec    1.00     32.8±0.23µs        ? ?/sec
divide_by_zero_protection/8192 rows, 10% zeros: DivideByZeroProtection                                                            2.08     95.6±1.22µs        ? ?/sec    1.00     46.1±0.50µs        ? ?/sec
divide_by_zero_protection/8192 rows, 50% zeros: DivideByZeroProtection                                                            1.51    134.8±2.85µs        ? ?/sec    1.00     89.3±0.57µs        ? ?/sec
divide_by_zero_protection/8192 rows, 90% zeros: DivideByZeroProtection                                                            1.00     58.5±0.43µs        ? ?/sec    1.42     83.3±0.54µs        ? ?/sec

For some reason the CI is now failing on this PR

When #20097 is merged, then we can run the benchmarks again and see how much additional boost this special case gives us

@pepijnve
Copy link
Contributor

pepijnve commented Feb 3, 2026

For some reason the CI is now failing on this PR

That's due to #19994 (comment)

github-merge-queue bot pushed a commit that referenced this pull request Feb 3, 2026
…0097)

## Which issue does this PR close?

- Related to #11570

## Rationale for this change

While reviewing #19994 it became clear the optimised
`ExpressionOrExpression` code path was not being used when the case
expression has no `else` branch or has `else null`. In those situations
the general evaluation strategies could end up being used.
This PR refines the `ExpressionOrExpression` implementation to also
handle `else null` expressions.

## What changes are included in this PR?

Use `ExpressionOrExpression` for expressions of the form `CASE WHEN x
THEN y [ELSE NULL]`

## Are these changes tested?

Covered by existing SLTs

## Are there any user-facing changes?

No
@CuteChuanChuan CuteChuanChuan force-pushed the raymond/11570-optimize-case-when branch from 4319634 to 0a8f085 Compare February 4, 2026 15:42
@alamb
Copy link
Contributor

alamb commented Feb 4, 2026

run benchmark case_when

@alamb-ghbot

This comment was marked as outdated.

@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 (0a8f085) to 796c7d1 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.01    125.9±1.67µs        ? ?/sec    1.00    125.0±1.96µs        ? ?/sec
case_when 8192x100: CASE WHEN c1 <= 500 THEN 1 ELSE 0 END                                                                         1.00     14.8±0.13µs        ? ?/sec    1.00     14.8±0.20µs        ? ?/sec
case_when 8192x100: CASE WHEN c1 <= 500 THEN c2 ELSE c3 END                                                                       1.02     17.1±0.36µs        ? ?/sec    1.00     16.8±0.07µs        ? ?/sec
case_when 8192x100: CASE WHEN c1 <= 500 THEN c2 [ELSE NULL] END                                                                   1.00      6.5±0.03µs        ? ?/sec    1.01      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.02     49.2±0.43ms        ? ?/sec    1.00     48.4±0.22ms        ? ?/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.7±0.62µs        ? ?/sec    1.00     42.9±0.66µs        ? ?/sec
case_when 8192x100: CASE c1 WHEN 1 THEN c2 WHEN 2 THEN c3 END                                                                     1.00     29.5±0.74µs        ? ?/sec    1.00     29.6±0.74µ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     37.5±0.73µs        ? ?/sec    1.04     39.0±2.53µ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    126.1±1.75µs        ? ?/sec    1.00    125.6±2.78µs        ? ?/sec
case_when 8192x3: CASE WHEN c1 <= 500 THEN 1 ELSE 0 END                                                                           1.00     14.8±0.22µs        ? ?/sec    1.00     14.7±0.05µs        ? ?/sec
case_when 8192x3: CASE WHEN c1 <= 500 THEN c2 ELSE c3 END                                                                         1.01     16.9±0.46µs        ? ?/sec    1.00     16.6±0.34µs        ? ?/sec
case_when 8192x3: CASE WHEN c1 <= 500 THEN c2 [ELSE NULL] END                                                                     1.00      6.6±0.37µs        ? ?/sec    1.01      6.6±0.07µ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.02     49.3±1.13ms        ? ?/sec    1.00     48.5±0.29ms        ? ?/sec
case_when 8192x3: CASE c1 WHEN 0 THEN 0 WHEN 1 THEN 1 ... WHEN n THEN n ELSE n + 1 END                                            1.00     42.1±0.52µs        ? ?/sec    1.01     42.7±0.65µs        ? ?/sec
case_when 8192x3: CASE c1 WHEN 1 THEN c2 WHEN 2 THEN c3 END                                                                       1.03     29.8±0.82µs        ? ?/sec    1.00     29.0±0.57µ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     37.5±0.82µs        ? ?/sec    1.02     38.5±0.60µ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.01    126.2±1.48µs        ? ?/sec    1.00    125.1±1.48µs        ? ?/sec
case_when 8192x50: CASE WHEN c1 <= 500 THEN 1 ELSE 0 END                                                                          1.00     14.9±0.24µs        ? ?/sec    1.00     14.9±0.08µs        ? ?/sec
case_when 8192x50: CASE WHEN c1 <= 500 THEN c2 ELSE c3 END                                                                        1.00     17.2±0.37µs        ? ?/sec    1.00     17.3±0.41µs        ? ?/sec
case_when 8192x50: CASE WHEN c1 <= 500 THEN c2 [ELSE NULL] END                                                                    1.00      6.5±0.04µs        ? ?/sec    1.02      6.6±0.08µ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.01     49.3±0.60ms        ? ?/sec    1.00     48.8±0.96ms        ? ?/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.2±1.26µs        ? ?/sec    1.02     43.0±0.55µs        ? ?/sec
case_when 8192x50: CASE c1 WHEN 1 THEN c2 WHEN 2 THEN c3 END                                                                      1.02     30.5±2.18µs        ? ?/sec    1.00     29.9±1.29µ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     37.5±0.58µs        ? ?/sec    1.03     38.5±0.55µs        ? ?/sec
divide_by_zero_protection/8192 rows, 0% zeros: DivideByZeroProtection                                                             1.00     26.1±0.15µs        ? ?/sec    1.10     28.7±0.15µs        ? ?/sec
divide_by_zero_protection/8192 rows, 10% zeros: DivideByZeroProtection                                                            1.50     63.2±1.10µs        ? ?/sec    1.00     42.2±0.31µs        ? ?/sec
divide_by_zero_protection/8192 rows, 50% zeros: DivideByZeroProtection                                                            1.00     84.4±0.37µs        ? ?/sec    1.03     86.9±0.98µs        ? ?/sec
divide_by_zero_protection/8192 rows, 90% zeros: DivideByZeroProtection                                                            1.00     31.0±0.15µs        ? ?/sec    2.51     77.8±0.68µ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    106.0±1.45µs        ? ?/sec    1.11    117.4±0.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.1         1.00    119.9±0.73µs        ? ?/sec    1.11    133.7±3.90µ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    124.4±1.52µs        ? ?/sec    1.11    137.8±1.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           1.00    106.0±1.48µs        ? ?/sec    1.11    117.9±1.75µ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    119.8±1.20µs        ? ?/sec    1.13    135.2±1.73µ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    123.4±0.64µs        ? ?/sec    1.11    137.4±0.61µ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    106.2±1.72µs        ? ?/sec    1.11    117.4±0.61µ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    120.0±1.66µs        ? ?/sec    1.12    134.6±3.31µ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    105.8±0.69µs        ? ?/sec    1.11    117.3±1.17µ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     98.7±2.65µs        ? ?/sec    1.12    110.8±2.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.1, nulls: 0.1    1.00    108.7±1.39µs        ? ?/sec    1.10    119.8±1.00µ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    109.7±1.13µs        ? ?/sec    1.11    121.5±1.51µ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     97.9±1.64µs        ? ?/sec    1.12    110.1±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    1.00    108.8±0.91µs        ? ?/sec    1.11    120.4±1.18µ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    110.0±1.87µs        ? ?/sec    1.11    122.4±3.47µ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     98.5±1.94µs        ? ?/sec    1.12    110.6±1.65µ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    109.1±2.52µs        ? ?/sec    1.10    120.2±1.16µ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     98.5±1.97µs        ? ?/sec    1.12    110.4±2.17µ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    108.9±3.33µs        ? ?/sec    1.10    119.3±1.55µ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    120.7±1.50µs        ? ?/sec    1.11    133.4±1.82µ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    133.7±1.98µs        ? ?/sec    1.11    148.2±1.89µ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    108.6±2.32µs        ? ?/sec    1.10    119.1±1.45µ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    121.0±1.87µs        ? ?/sec    1.11    133.7±2.01µ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    133.1±1.17µs        ? ?/sec    1.11    147.9±1.16µ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    108.9±2.88µs        ? ?/sec    1.10    119.4±1.43µ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    120.9±1.73µs        ? ?/sec    1.11    133.8±2.10µ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    109.0±2.49µs        ? ?/sec    1.10    119.5±1.61µ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     98.1±1.14µs        ? ?/sec    1.12    110.2±1.33µ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    108.5±1.44µs        ? ?/sec    1.10    119.9±1.31µ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    109.7±1.18µs        ? ?/sec    1.11    121.5±0.50µ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     98.3±2.04µs        ? ?/sec    1.12    110.5±5.41µ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    108.8±1.05µs        ? ?/sec    1.11    120.4±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.5    1.00    109.7±1.19µs        ? ?/sec    1.11    121.9±1.38µ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     98.4±1.30µs        ? ?/sec    1.12    110.2±1.65µ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    108.5±0.62µs        ? ?/sec    1.11    120.0±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: 1, nulls: 0        1.00     98.9±5.42µs        ? ?/sec    1.12    110.5±2.02µ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    106.5±1.12µs        ? ?/sec    1.11    118.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.1, nulls: 0.1          1.00    118.4±2.11µs        ? ?/sec    1.11    131.0±1.70µ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    117.4±0.68µs        ? ?/sec    1.12    131.0±1.13µ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    106.1±0.60µs        ? ?/sec    1.11    117.8±1.33µ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    118.1±0.65µs        ? ?/sec    1.11    130.8±1.28µ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    117.8±1.53µs        ? ?/sec    1.11    131.2±1.15µ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    106.3±1.09µs        ? ?/sec    1.11    117.9±2.11µ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    118.5±1.75µs        ? ?/sec    1.10    130.9±1.21µ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    106.4±1.60µs        ? ?/sec    1.11    118.0±1.46µ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     98.3±2.13µs        ? ?/sec    1.12    109.7±0.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.1, nulls: 0.1     1.00    108.3±0.93µs        ? ?/sec    1.11    120.6±2.11µ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    109.9±1.79µs        ? ?/sec    1.11    122.0±1.29µ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     98.1±1.34µs        ? ?/sec    1.12    110.2±1.61µ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    108.6±1.18µs        ? ?/sec    1.11    120.2±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.5, nulls: 0.5     1.00    109.4±1.29µs        ? ?/sec    1.11    121.9±1.29µ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     98.5±1.50µs        ? ?/sec    1.13    111.0±1.53µ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    108.7±0.83µs        ? ?/sec    1.11    120.4±1.82µ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     98.6±1.82µs        ? ?/sec    1.12    110.5±1.90µ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.03    146.2±4.01µs        ? ?/sec    1.00    142.5±3.59µ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.06    157.0±5.82µs        ? ?/sec    1.00    147.6±2.82µ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.01    137.0±2.35µs        ? ?/sec    1.00    135.9±2.02µ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.02    145.8±3.21µs        ? ?/sec    1.00    142.4±2.94µ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.01    150.2±2.83µs        ? ?/sec    1.00    149.0±4.69µ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    136.5±1.33µs        ? ?/sec    1.03    141.1±2.08µ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.01    146.1±4.20µs        ? ?/sec    1.00    144.7±6.10µ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.02    150.9±3.32µs        ? ?/sec    1.00    147.8±2.85µ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.03    145.8±2.73µs        ? ?/sec    1.00    142.2±2.44µ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    138.0±4.44µs        ? ?/sec    1.01    138.9±4.85µ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.02    140.6±3.59µs        ? ?/sec    1.00    138.4±1.46µ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    131.0±2.37µs        ? ?/sec    1.01    131.7±0.75µ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.02    136.4±3.33µs        ? ?/sec    1.00    133.9±0.85µ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    138.2±1.21µs        ? ?/sec    1.00    138.6±1.69µ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    132.1±0.53µs        ? ?/sec    1.00    131.7±0.41µ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.2±1.26µs        ? ?/sec    1.00    136.6±4.71µ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.01    139.8±3.46µs        ? ?/sec    1.00    138.3±1.42µ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    138.7±5.86µs        ? ?/sec    1.01    140.6±6.70µ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.03    145.1±3.06µs        ? ?/sec    1.00    141.1±1.39µ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.01    147.1±3.09µs        ? ?/sec    1.00    146.0±2.21µ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    134.3±1.56µs        ? ?/sec    1.00    134.8±1.07µ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.01    144.9±3.46µs        ? ?/sec    1.00    143.1±3.02µ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    148.5±2.85µs        ? ?/sec    1.00    147.0±2.19µ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    134.1±0.93µs        ? ?/sec    1.01    135.0±1.02µ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.02    145.4±2.31µs        ? ?/sec    1.00    142.0±2.56µ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    147.6±2.61µs        ? ?/sec    1.00    147.1±2.55µ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.01    146.0±9.86µs        ? ?/sec    1.00    143.9±2.56µ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    137.3±1.01µs        ? ?/sec    1.01    139.3±5.75µ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.01    140.8±4.06µs        ? ?/sec    1.00    138.8±7.63µ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.5±0.44µs        ? ?/sec    1.01    131.5±0.42µ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.31µs        ? ?/sec    1.02    137.7±5.31µ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.6±1.29µs        ? ?/sec    1.00    138.3±1.23µ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    131.9±0.57µs        ? ?/sec    1.01    132.7±2.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.9, nulls: 0      1.00    136.9±1.66µs        ? ?/sec    1.00    137.3±4.95µ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.7±1.45µs        ? ?/sec    1.02    141.6±4.13µ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    136.3±3.76µs        ? ?/sec    1.03    140.2±8.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.09    155.6±4.93µs        ? ?/sec    1.00    143.4±1.86µ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.03    150.5±3.45µs        ? ?/sec    1.00    146.8±3.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.5          1.00    136.6±0.66µs        ? ?/sec    1.04    141.5±5.27µ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.03    147.9±0.99µs        ? ?/sec    1.00    142.9±1.98µ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.02    150.7±3.65µs        ? ?/sec    1.00    147.1±2.96µ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.01    137.8±2.41µs        ? ?/sec    1.00    137.0±1.39µ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.04    148.6±2.69µs        ? ?/sec    1.00    143.0±0.91µ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.02    151.2±5.03µs        ? ?/sec    1.00    147.8±2.25µ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.04    148.5±3.84µs        ? ?/sec    1.00    143.0±3.86µ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.01    137.9±1.58µs        ? ?/sec    1.00    137.1±2.88µ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.02    140.1±1.28µs        ? ?/sec    1.00    137.7±0.74µ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    131.1±1.35µs        ? ?/sec    1.00    131.6±0.70µ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.01    135.9±2.24µs        ? ?/sec    1.00    134.0±1.37µ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    138.6±1.19µs        ? ?/sec    1.00    138.0±0.96µ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    131.7±0.48µs        ? ?/sec    1.06    139.9±2.66µ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.03    138.3±2.81µs        ? ?/sec    1.00    134.0±0.64µ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.01    139.8±1.27µs        ? ?/sec    1.00    138.1±1.15µ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.01    135.7±0.95µs        ? ?/sec    1.00    134.4±1.59µs        ? ?/sec

@CuteChuanChuan
Copy link
Contributor Author

It seems that effect of Divide by zero protection is not significant.🤣

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