Skip to content

Commit 60d165d

Browse files
authored
Add Kleene boolean benchmarks (#8476)
Signed-off-by: "Nicholas Gates" <nick@nickgates.com>
1 parent 8058097 commit 60d165d

2 files changed

Lines changed: 234 additions & 0 deletions

File tree

vortex-array/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,10 @@ harness = false
130130
name = "binary_ops"
131131
harness = false
132132

133+
[[bench]]
134+
name = "kleene_bool"
135+
harness = false
136+
133137
[[bench]]
134138
name = "interleave"
135139
harness = false
Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
// SPDX-FileCopyrightText: Copyright the Vortex contributors
3+
4+
#![expect(clippy::unwrap_used)]
5+
6+
use std::sync::LazyLock;
7+
8+
use divan::Bencher;
9+
use divan::counter::ItemsCount;
10+
use vortex_array::ArrayRef;
11+
use vortex_array::Columnar;
12+
use vortex_array::IntoArray;
13+
use vortex_array::VortexSessionExecute;
14+
use vortex_array::arrays::BoolArray;
15+
use vortex_array::arrays::ConstantArray;
16+
use vortex_array::arrow::ArrowSession;
17+
use vortex_array::builtins::ArrayBuiltins;
18+
use vortex_array::dtype::DType;
19+
use vortex_array::dtype::Nullability;
20+
use vortex_array::scalar::Scalar;
21+
use vortex_array::scalar_fn::fns::operators::Operator;
22+
use vortex_array::session::ArraySession;
23+
use vortex_session::VortexSession;
24+
25+
fn main() {
26+
divan::main();
27+
}
28+
29+
static SESSION: LazyLock<VortexSession> = LazyLock::new(|| {
30+
VortexSession::empty()
31+
.with::<ArraySession>()
32+
.with::<ArrowSession>()
33+
});
34+
35+
const LEN: usize = 65_536;
36+
const SHIFTED_OFFSET: usize = 1;
37+
38+
#[divan::bench]
39+
fn and_bool_nonnull_arrays(bencher: Bencher) {
40+
bench_kleene(
41+
bencher,
42+
bool_nonnull(2).into_array(),
43+
bool_nonnull(3).into_array(),
44+
Operator::And,
45+
);
46+
}
47+
48+
#[divan::bench]
49+
fn or_bool_nonnull_arrays(bencher: Bencher) {
50+
bench_kleene(
51+
bencher,
52+
bool_nonnull(2).into_array(),
53+
bool_nonnull(3).into_array(),
54+
Operator::Or,
55+
);
56+
}
57+
58+
#[divan::bench]
59+
fn and_bool_nullable_arrays(bencher: Bencher) {
60+
and_bool_nullable_arrays_aligned(bencher);
61+
}
62+
63+
#[divan::bench]
64+
fn and_bool_nullable_arrays_aligned(bencher: Bencher) {
65+
bench_kleene(
66+
bencher,
67+
bool_nullable(2, 7, 0),
68+
bool_nullable(3, 5, 0),
69+
Operator::And,
70+
);
71+
}
72+
73+
#[divan::bench]
74+
fn or_bool_nullable_arrays(bencher: Bencher) {
75+
or_bool_nullable_arrays_aligned(bencher);
76+
}
77+
78+
#[divan::bench]
79+
fn or_bool_nullable_arrays_aligned(bencher: Bencher) {
80+
bench_kleene(
81+
bencher,
82+
bool_nullable(2, 7, 0),
83+
bool_nullable(3, 5, 0),
84+
Operator::Or,
85+
);
86+
}
87+
88+
#[divan::bench]
89+
fn and_bool_nullable_arrays_shifted(bencher: Bencher) {
90+
bench_kleene(
91+
bencher,
92+
bool_nullable(2, 7, SHIFTED_OFFSET),
93+
bool_nullable(3, 5, SHIFTED_OFFSET),
94+
Operator::And,
95+
);
96+
}
97+
98+
#[divan::bench]
99+
fn or_bool_nullable_arrays_shifted(bencher: Bencher) {
100+
bench_kleene(
101+
bencher,
102+
bool_nullable(2, 7, SHIFTED_OFFSET),
103+
bool_nullable(3, 5, SHIFTED_OFFSET),
104+
Operator::Or,
105+
);
106+
}
107+
108+
#[divan::bench]
109+
fn and_true_constant(bencher: Bencher) {
110+
bench_kleene(
111+
bencher,
112+
bool_nullable(2, 7, 0),
113+
ConstantArray::new(true, LEN).into_array(),
114+
Operator::And,
115+
);
116+
}
117+
118+
#[divan::bench]
119+
fn or_false_constant(bencher: Bencher) {
120+
bench_kleene(
121+
bencher,
122+
bool_nullable(2, 7, 0),
123+
ConstantArray::new(false, LEN).into_array(),
124+
Operator::Or,
125+
);
126+
}
127+
128+
#[divan::bench]
129+
fn and_false_constant(bencher: Bencher) {
130+
bench_kleene(
131+
bencher,
132+
bool_nullable(2, 7, 0),
133+
ConstantArray::new(false, LEN).into_array(),
134+
Operator::And,
135+
);
136+
}
137+
138+
#[divan::bench]
139+
fn or_true_constant(bencher: Bencher) {
140+
bench_kleene(
141+
bencher,
142+
bool_nullable(2, 7, 0),
143+
ConstantArray::new(true, LEN).into_array(),
144+
Operator::Or,
145+
);
146+
}
147+
148+
#[divan::bench]
149+
fn and_null_constant(bencher: Bencher) {
150+
and_null_constant_aligned(bencher);
151+
}
152+
153+
#[divan::bench]
154+
fn and_null_constant_aligned(bencher: Bencher) {
155+
bench_kleene(
156+
bencher,
157+
bool_nullable(2, 7, 0),
158+
null_bool_constant(),
159+
Operator::And,
160+
);
161+
}
162+
163+
#[divan::bench]
164+
fn or_null_constant(bencher: Bencher) {
165+
or_null_constant_aligned(bencher);
166+
}
167+
168+
#[divan::bench]
169+
fn or_null_constant_aligned(bencher: Bencher) {
170+
bench_kleene(
171+
bencher,
172+
bool_nullable(2, 7, 0),
173+
null_bool_constant(),
174+
Operator::Or,
175+
);
176+
}
177+
178+
#[divan::bench]
179+
fn and_null_constant_shifted(bencher: Bencher) {
180+
bench_kleene(
181+
bencher,
182+
bool_nullable(2, 7, SHIFTED_OFFSET),
183+
null_bool_constant(),
184+
Operator::And,
185+
);
186+
}
187+
188+
#[divan::bench]
189+
fn or_null_constant_shifted(bencher: Bencher) {
190+
bench_kleene(
191+
bencher,
192+
bool_nullable(2, 7, SHIFTED_OFFSET),
193+
null_bool_constant(),
194+
Operator::Or,
195+
);
196+
}
197+
198+
fn bench_kleene(bencher: Bencher, lhs: ArrayRef, rhs: ArrayRef, operator: Operator) {
199+
let mut ctx = SESSION.create_execution_ctx();
200+
201+
bencher.counter(ItemsCount::new(LEN)).bench_local(|| {
202+
lhs.clone()
203+
.binary(rhs.clone(), operator)
204+
.unwrap()
205+
.execute::<Columnar>(&mut ctx)
206+
.unwrap()
207+
});
208+
}
209+
210+
fn bool_nonnull(true_every: usize) -> BoolArray {
211+
BoolArray::from_iter((0..LEN).map(|i| i.is_multiple_of(true_every)))
212+
}
213+
214+
fn bool_nullable(true_every: usize, null_every: usize, offset: usize) -> ArrayRef {
215+
let len = LEN + offset;
216+
let array = BoolArray::from_iter(
217+
(0..len).map(|i| (!i.is_multiple_of(null_every)).then_some(i.is_multiple_of(true_every))),
218+
)
219+
.into_array();
220+
221+
if offset == 0 {
222+
array
223+
} else {
224+
array.slice(offset..offset + LEN).unwrap()
225+
}
226+
}
227+
228+
fn null_bool_constant() -> ArrayRef {
229+
ConstantArray::new(Scalar::null(DType::Bool(Nullability::Nullable)), LEN).into_array()
230+
}

0 commit comments

Comments
 (0)