@@ -14,7 +14,13 @@ use vortex_array::IntoArray;
1414use vortex_array:: VortexSessionExecute ;
1515use vortex_array:: array_session;
1616use vortex_array:: arrays:: BoolArray ;
17+ use vortex_array:: arrays:: ConstantArray ;
18+ use vortex_array:: arrays:: DecimalArray ;
19+ use vortex_array:: arrays:: ScalarFnArray ;
1720use vortex_array:: arrays:: StructArray ;
21+ use vortex_array:: arrays:: VarBinViewArray ;
22+ use vortex_array:: builtins:: ArrayBuiltins ;
23+ use vortex_array:: dtype:: DecimalDType ;
1824use vortex_array:: expr:: case_when;
1925use vortex_array:: expr:: case_when_no_else;
2026use vortex_array:: expr:: eq;
@@ -24,6 +30,12 @@ use vortex_array::expr::lit;
2430use vortex_array:: expr:: lt;
2531use vortex_array:: expr:: nested_case_when;
2632use vortex_array:: expr:: root;
33+ use vortex_array:: scalar:: Scalar ;
34+ use vortex_array:: scalar_fn:: ScalarFnVTableExt ;
35+ use vortex_array:: scalar_fn:: fns:: case_when:: CaseWhen ;
36+ use vortex_array:: scalar_fn:: fns:: case_when:: CaseWhenOptions ;
37+ use vortex_array:: scalar_fn:: fns:: operators:: Operator ;
38+ use vortex_array:: validity:: Validity ;
2739use vortex_buffer:: Buffer ;
2840use vortex_session:: VortexSession ;
2941
@@ -37,6 +49,53 @@ fn main() {
3749 divan:: main ( ) ;
3850}
3951
52+ #[ divan:: bench( args = [ 1 , 4 , 16 , 64 , 256 , 4096 ] ) ]
53+ fn case_when_decimal_product ( bencher : Bencher , run_length : usize ) {
54+ let len = 65_536 ;
55+ let lhs = DecimalArray :: new (
56+ Buffer :: from_iter ( ( 0 ..len) . map ( |i| ( i % 10_000 ) as i64 ) ) ,
57+ DecimalDType :: new ( 15 , 2 ) ,
58+ Validity :: NonNullable ,
59+ )
60+ . into_array ( ) ;
61+ let rhs = DecimalArray :: new (
62+ Buffer :: from_iter ( ( 0 ..len) . map ( |i| ( i % 100 ) as i64 ) ) ,
63+ DecimalDType :: new ( 15 , 2 ) ,
64+ Validity :: NonNullable ,
65+ )
66+ . into_array ( ) ;
67+ let product = lhs. binary ( rhs, Operator :: Mul ) . unwrap ( ) ;
68+ let otherwise = ConstantArray :: new ( Scalar :: zero_value ( product. dtype ( ) ) , len) . into_array ( ) ;
69+ bench_branches ( bencher, run_length, product, otherwise) ;
70+ }
71+
72+ #[ divan:: bench( args = [ 1 , 4 , 16 , 64 , 256 , 4096 ] ) ]
73+ fn case_when_string_values ( bencher : Bencher , run_length : usize ) {
74+ let len = 65_536 ;
75+ let lhs = VarBinViewArray :: from_iter_str ( ( 0 ..len) . map ( |i| format ! ( "long-left-value-{i}" ) ) )
76+ . into_array ( ) ;
77+ let rhs = VarBinViewArray :: from_iter_str ( ( 0 ..len) . map ( |i| format ! ( "long-right-value-{i}" ) ) )
78+ . into_array ( ) ;
79+ bench_branches ( bencher, run_length, lhs, rhs) ;
80+ }
81+
82+ fn bench_branches ( bencher : Bencher , run_length : usize , lhs : ArrayRef , rhs : ArrayRef ) {
83+ let mask = BoolArray :: from_iter ( ( 0 ..lhs. len ( ) ) . map ( |i| ( i / run_length) . is_multiple_of ( 2 ) ) )
84+ . into_array ( ) ;
85+ let array = ScalarFnArray :: try_new (
86+ CaseWhen . bind ( CaseWhenOptions {
87+ num_when_then_pairs : 1 ,
88+ has_else : true ,
89+ } ) ,
90+ vec ! [ mask, lhs, rhs] ,
91+ )
92+ . unwrap ( )
93+ . into_array ( ) ;
94+ bencher
95+ . with_inputs ( || SESSION . create_execution_ctx ( ) )
96+ . bench_refs ( |ctx| array. clone ( ) . execute :: < Canonical > ( ctx) . unwrap ( ) ) ;
97+ }
98+
4099fn make_struct_array ( size : usize ) -> ArrayRef {
41100 let data: Buffer < i32 > = ( 0 ..size as i32 ) . collect ( ) ;
42101 let field = data. into_array ( ) ;
@@ -264,7 +323,7 @@ fn case_when_all_false(bencher: Bencher, size: usize) {
264323 } ) ;
265324}
266325
267- /// Benchmark CASE WHEN cycling through 3 branches per row (triggers merge_row_by_row) .
326+ /// Benchmark compact CASE WHEN assembly with three interleaved branches .
268327/// Run length = 1; exercises branch 0, branch 1, and the else fallback at every 3rd row.
269328#[ divan:: bench( args = [ 100 , 400 ] ) ]
270329fn case_when_fragmented ( bencher : Bencher , size : usize ) {
0 commit comments