Skip to content

Commit 14524f6

Browse files
committed
N-ary
1 parent 359a4d4 commit 14524f6

3 files changed

Lines changed: 909 additions & 242 deletions

File tree

vortex-array/benches/expr/case_when_bench.rs

Lines changed: 93 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ use vortex_array::expr::case_when;
1616
use vortex_array::expr::get_item;
1717
use vortex_array::expr::gt;
1818
use vortex_array::expr::lit;
19-
use vortex_array::expr::nested_case_when;
2019
use vortex_array::expr::root;
2120
use vortex_array::session::ArraySession;
2221
use 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])]
4948
fn 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])]
100100
fn 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])]
124124
fn 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

Comments
 (0)