@@ -16,7 +16,6 @@ use vortex_array::expr::case_when;
1616use vortex_array:: expr:: get_item;
1717use vortex_array:: expr:: gt;
1818use vortex_array:: expr:: lit;
19- use vortex_array:: expr:: nested_case_when;
2019use vortex_array:: expr:: root;
2120use vortex_array:: session:: ArraySession ;
2221use vortex_array:: validity:: Validity ;
@@ -45,16 +44,16 @@ fn make_struct_array(size: usize) -> ArrayRef {
4544}
4645
4746/// Benchmark a simple binary CASE WHEN with varying array sizes.
48- #[ divan:: bench( args = [ 1000 , 10000 , 100000 ] ) ]
47+ #[ divan:: bench( args = [ 10000 , 100000 , 1000000 ] ) ]
4948fn case_when_simple ( bencher : Bencher , size : usize ) {
5049 let array = make_struct_array ( size) ;
5150
5251 // CASE WHEN value > 500 THEN 100 ELSE 0 END
53- let expr = case_when (
52+ let expr = case_when ( [
5453 gt ( get_item ( "value" , root ( ) ) , lit ( 500i32 ) ) ,
5554 lit ( 100i32 ) ,
5655 lit ( 0i32 ) ,
57- ) ;
56+ ] ) ;
5857
5958 bencher
6059 . with_inputs ( || ( & expr, & array) )
@@ -68,20 +67,21 @@ fn case_when_simple(bencher: Bencher, size: usize) {
6867 } ) ;
6968}
7069
71- /// Benchmark nested CASE WHEN with multiple conditions.
72- #[ divan:: bench( args = [ 1000 , 10000 , 100000 ] ) ]
73- fn case_when_nested_3_conditions ( bencher : Bencher , size : usize ) {
70+ /// Benchmark n-ary CASE WHEN with multiple conditions.
71+ #[ divan:: bench( args = [ 10000 , 100000 , 1000000 ] ) ]
72+ fn case_when_nary_3_conditions ( bencher : Bencher , size : usize ) {
7473 let array = make_struct_array ( size) ;
7574
7675 // CASE WHEN value > 750 THEN 3 WHEN value > 500 THEN 2 WHEN value > 250 THEN 1 ELSE 0 END
77- let expr = nested_case_when (
78- vec ! [
79- ( gt( get_item( "value" , root( ) ) , lit( 750i32 ) ) , lit( 3i32 ) ) ,
80- ( gt( get_item( "value" , root( ) ) , lit( 500i32 ) ) , lit( 2i32 ) ) ,
81- ( gt( get_item( "value" , root( ) ) , lit( 250i32 ) ) , lit( 1i32 ) ) ,
82- ] ,
83- Some ( lit ( 0i32 ) ) ,
84- ) ;
76+ let expr = case_when ( [
77+ gt ( get_item ( "value" , root ( ) ) , lit ( 750i32 ) ) ,
78+ lit ( 3i32 ) ,
79+ gt ( get_item ( "value" , root ( ) ) , lit ( 500i32 ) ) ,
80+ lit ( 2i32 ) ,
81+ gt ( get_item ( "value" , root ( ) ) , lit ( 250i32 ) ) ,
82+ lit ( 1i32 ) ,
83+ lit ( 0i32 ) ,
84+ ] ) ;
8585
8686 bencher
8787 . with_inputs ( || ( & expr, & array) )
@@ -96,16 +96,16 @@ fn case_when_nested_3_conditions(bencher: Bencher, size: usize) {
9696}
9797
9898/// Benchmark CASE WHEN where all conditions are true (short-circuit path).
99- #[ divan:: bench( args = [ 1000 , 10000 , 100000 ] ) ]
99+ #[ divan:: bench( args = [ 10000 , 100000 , 1000000 ] ) ]
100100fn case_when_all_true ( bencher : Bencher , size : usize ) {
101101 let array = make_struct_array ( size) ;
102102
103103 // CASE WHEN value >= 0 THEN 100 ELSE 0 END (always true for our data)
104- let expr = case_when (
104+ let expr = case_when ( [
105105 gt ( get_item ( "value" , root ( ) ) , lit ( -1i32 ) ) ,
106106 lit ( 100i32 ) ,
107107 lit ( 0i32 ) ,
108- ) ;
108+ ] ) ;
109109
110110 bencher
111111 . with_inputs ( || ( & expr, & array) )
@@ -120,16 +120,88 @@ fn case_when_all_true(bencher: Bencher, size: usize) {
120120}
121121
122122/// Benchmark CASE WHEN where all conditions are false (short-circuit path).
123- #[ divan:: bench( args = [ 1000 , 10000 , 100000 ] ) ]
123+ #[ divan:: bench( args = [ 10000 , 100000 , 1000000 ] ) ]
124124fn case_when_all_false ( bencher : Bencher , size : usize ) {
125125 let array = make_struct_array ( size) ;
126126
127127 // CASE WHEN value > 1000000 THEN 100 ELSE 0 END (always false for our data)
128- let expr = case_when (
128+ let expr = case_when ( [
129129 gt ( get_item ( "value" , root ( ) ) , lit ( 1_000_000i32 ) ) ,
130130 lit ( 100i32 ) ,
131131 lit ( 0i32 ) ,
132- ) ;
132+ ] ) ;
133+
134+ bencher
135+ . with_inputs ( || ( & expr, & array) )
136+ . bench_refs ( |( expr, array) | {
137+ let mut ctx = SESSION . create_execution_ctx ( ) ;
138+ array
139+ . apply ( expr)
140+ . unwrap ( )
141+ . execute :: < Canonical > ( & mut ctx)
142+ . unwrap ( )
143+ } ) ;
144+ }
145+
146+ /// Benchmark n-ary CASE WHEN with 10 conditions.
147+ #[ divan:: bench( args = [ 10000 , 100000 , 1000000 ] ) ]
148+ fn case_when_nary_10_conditions ( bencher : Bencher , size : usize ) {
149+ let array = make_struct_array ( size) ;
150+
151+ // Build 10 WHEN/THEN pairs with decreasing thresholds
152+ let expr = case_when ( [
153+ gt ( get_item ( "value" , root ( ) ) , lit ( 900i32 ) ) ,
154+ lit ( 10i32 ) ,
155+ gt ( get_item ( "value" , root ( ) ) , lit ( 800i32 ) ) ,
156+ lit ( 9i32 ) ,
157+ gt ( get_item ( "value" , root ( ) ) , lit ( 700i32 ) ) ,
158+ lit ( 8i32 ) ,
159+ gt ( get_item ( "value" , root ( ) ) , lit ( 600i32 ) ) ,
160+ lit ( 7i32 ) ,
161+ gt ( get_item ( "value" , root ( ) ) , lit ( 500i32 ) ) ,
162+ lit ( 6i32 ) ,
163+ gt ( get_item ( "value" , root ( ) ) , lit ( 400i32 ) ) ,
164+ lit ( 5i32 ) ,
165+ gt ( get_item ( "value" , root ( ) ) , lit ( 300i32 ) ) ,
166+ lit ( 4i32 ) ,
167+ gt ( get_item ( "value" , root ( ) ) , lit ( 200i32 ) ) ,
168+ lit ( 3i32 ) ,
169+ gt ( get_item ( "value" , root ( ) ) , lit ( 100i32 ) ) ,
170+ lit ( 2i32 ) ,
171+ gt ( get_item ( "value" , root ( ) ) , lit ( 0i32 ) ) ,
172+ lit ( 1i32 ) ,
173+ lit ( 0i32 ) , // else
174+ ] ) ;
175+
176+ bencher
177+ . with_inputs ( || ( & expr, & array) )
178+ . bench_refs ( |( expr, array) | {
179+ let mut ctx = SESSION . create_execution_ctx ( ) ;
180+ array
181+ . apply ( expr)
182+ . unwrap ( )
183+ . execute :: < Canonical > ( & mut ctx)
184+ . unwrap ( )
185+ } ) ;
186+ }
187+
188+ /// Benchmark n-ary CASE WHEN with 100 conditions.
189+ #[ divan:: bench( args = [ 10000 , 100000 , 1000000 ] ) ]
190+ fn case_when_nary_100_conditions ( bencher : Bencher , size : usize ) {
191+ use vortex_array:: expr:: Expression ;
192+
193+ let array = make_struct_array ( size) ;
194+
195+ // Build 100 WHEN/THEN pairs programmatically
196+ let mut children: Vec < Expression > = Vec :: with_capacity ( 201 ) ;
197+ for i in ( 1 ..=100 ) . rev ( ) {
198+ let threshold = i * 10 ; // thresholds: 1000, 990, 980, ..., 10
199+ children. push ( gt ( get_item ( "value" , root ( ) ) , lit ( threshold as i32 ) ) ) ;
200+ children. push ( lit ( i as i32 ) ) ;
201+ }
202+ children. push ( lit ( 0i32 ) ) ; // else
203+
204+ let expr = case_when ( children) ;
133205
134206 bencher
135207 . with_inputs ( || ( & expr, & array) )
0 commit comments