Skip to content

Commit d6c560f

Browse files
committed
Run boolean and bitwise kernels for longer to reduce noise
1 parent 389f404 commit d6c560f

File tree

2 files changed

+79
-33
lines changed

2 files changed

+79
-33
lines changed

arrow/benches/bitwise_kernel.rs

Lines changed: 57 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,15 @@ extern crate arrow;
3232
use arrow::util::bench_util::create_primitive_array;
3333
use arrow::util::test_util::seedable_rng;
3434

35+
// These bitwise kernels are very cheap, so run them many times per Criterion iteration
36+
const RUNS_PER_SAMPLE: usize = 1_000;
37+
38+
fn repeat_runs<T>(mut f: impl FnMut() -> T) {
39+
for _ in 0..RUNS_PER_SAMPLE {
40+
f();
41+
}
42+
}
43+
3544
fn bitwise_array_benchmark(c: &mut Criterion) {
3645
let size = 64 * 1024_usize;
3746
let left_without_null = create_primitive_array::<Int64Type>(size, 0 as f32);
@@ -41,37 +50,55 @@ fn bitwise_array_benchmark(c: &mut Criterion) {
4150
// array and
4251
let mut group = c.benchmark_group("bench bitwise array: and");
4352
group.bench_function("bitwise array and, no nulls", |b| {
44-
b.iter(|| hint::black_box(bitwise_and(&left_without_null, &right_without_null).unwrap()))
53+
b.iter(|| {
54+
repeat_runs(|| {
55+
hint::black_box(bitwise_and(&left_without_null, &right_without_null).unwrap())
56+
})
57+
})
4558
});
4659
group.bench_function("bitwise array and, 20% nulls", |b| {
47-
b.iter(|| hint::black_box(bitwise_and(&left_with_null, &right_with_null).unwrap()))
60+
b.iter(|| {
61+
repeat_runs(|| hint::black_box(bitwise_and(&left_with_null, &right_with_null).unwrap()))
62+
})
4863
});
4964
group.finish();
5065
// array or
5166
let mut group = c.benchmark_group("bench bitwise: or");
5267
group.bench_function("bitwise array or, no nulls", |b| {
53-
b.iter(|| hint::black_box(bitwise_or(&left_without_null, &right_without_null).unwrap()))
68+
b.iter(|| {
69+
repeat_runs(|| {
70+
hint::black_box(bitwise_or(&left_without_null, &right_without_null).unwrap())
71+
})
72+
})
5473
});
5574
group.bench_function("bitwise array or, 20% nulls", |b| {
56-
b.iter(|| hint::black_box(bitwise_or(&left_with_null, &right_with_null).unwrap()))
75+
b.iter(|| {
76+
repeat_runs(|| hint::black_box(bitwise_or(&left_with_null, &right_with_null).unwrap()))
77+
})
5778
});
5879
group.finish();
5980
// xor
6081
let mut group = c.benchmark_group("bench bitwise: xor");
6182
group.bench_function("bitwise array xor, no nulls", |b| {
62-
b.iter(|| hint::black_box(bitwise_xor(&left_without_null, &right_without_null).unwrap()))
83+
b.iter(|| {
84+
repeat_runs(|| {
85+
hint::black_box(bitwise_xor(&left_without_null, &right_without_null).unwrap())
86+
})
87+
})
6388
});
6489
group.bench_function("bitwise array xor, 20% nulls", |b| {
65-
b.iter(|| hint::black_box(bitwise_xor(&left_with_null, &right_with_null).unwrap()))
90+
b.iter(|| {
91+
repeat_runs(|| hint::black_box(bitwise_xor(&left_with_null, &right_with_null).unwrap()))
92+
})
6693
});
6794
group.finish();
6895
// not
6996
let mut group = c.benchmark_group("bench bitwise: not");
7097
group.bench_function("bitwise array not, no nulls", |b| {
71-
b.iter(|| hint::black_box(bitwise_not(&left_without_null).unwrap()))
98+
b.iter(|| repeat_runs(|| hint::black_box(bitwise_not(&left_without_null).unwrap())))
7299
});
73100
group.bench_function("bitwise array not, 20% nulls", |b| {
74-
b.iter(|| hint::black_box(bitwise_not(&left_with_null).unwrap()))
101+
b.iter(|| repeat_runs(|| hint::black_box(bitwise_not(&left_with_null).unwrap())))
75102
});
76103
group.finish();
77104
}
@@ -84,28 +111,44 @@ fn bitwise_array_scalar_benchmark(c: &mut Criterion) {
84111
// array scalar and
85112
let mut group = c.benchmark_group("bench bitwise array scalar: and");
86113
group.bench_function("bitwise array scalar and, no nulls", |b| {
87-
b.iter(|| hint::black_box(bitwise_and_scalar(&array_without_null, scalar).unwrap()))
114+
b.iter(|| {
115+
repeat_runs(|| {
116+
hint::black_box(bitwise_and_scalar(&array_without_null, scalar).unwrap())
117+
})
118+
})
88119
});
89120
group.bench_function("bitwise array and, 20% nulls", |b| {
90-
b.iter(|| hint::black_box(bitwise_and_scalar(&array_with_null, scalar).unwrap()))
121+
b.iter(|| {
122+
repeat_runs(|| hint::black_box(bitwise_and_scalar(&array_with_null, scalar).unwrap()))
123+
})
91124
});
92125
group.finish();
93126
// array scalar or
94127
let mut group = c.benchmark_group("bench bitwise array scalar: or");
95128
group.bench_function("bitwise array scalar or, no nulls", |b| {
96-
b.iter(|| hint::black_box(bitwise_or_scalar(&array_without_null, scalar).unwrap()))
129+
b.iter(|| {
130+
repeat_runs(|| hint::black_box(bitwise_or_scalar(&array_without_null, scalar).unwrap()))
131+
})
97132
});
98133
group.bench_function("bitwise array scalar or, 20% nulls", |b| {
99-
b.iter(|| hint::black_box(bitwise_or_scalar(&array_with_null, scalar).unwrap()))
134+
b.iter(|| {
135+
repeat_runs(|| hint::black_box(bitwise_or_scalar(&array_with_null, scalar).unwrap()))
136+
})
100137
});
101138
group.finish();
102139
// array scalar xor
103140
let mut group = c.benchmark_group("bench bitwise array scalar: xor");
104141
group.bench_function("bitwise array scalar xor, no nulls", |b| {
105-
b.iter(|| hint::black_box(bitwise_xor_scalar(&array_without_null, scalar).unwrap()))
142+
b.iter(|| {
143+
repeat_runs(|| {
144+
hint::black_box(bitwise_xor_scalar(&array_without_null, scalar).unwrap())
145+
})
146+
})
106147
});
107148
group.bench_function("bitwise array scalar xor, 20% nulls", |b| {
108-
b.iter(|| hint::black_box(bitwise_xor_scalar(&array_with_null, scalar).unwrap()))
149+
b.iter(|| {
150+
repeat_runs(|| hint::black_box(bitwise_xor_scalar(&array_with_null, scalar).unwrap()))
151+
})
109152
});
110153
group.finish();
111154
}

arrow/benches/boolean_kernels.rs

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -27,44 +27,47 @@ use arrow::array::*;
2727
use arrow::compute::kernels::boolean as boolean_kernels;
2828
use std::hint;
2929

30+
const ARRAY_LEN: usize = 8_192;
31+
// Repeat each kernel call RUNS_PER_SAMPLE times per Criterion iteration to drown out harness overhead
32+
const RUNS_PER_SAMPLE: usize = 1_000;
33+
3034
fn bench_and(lhs: &BooleanArray, rhs: &BooleanArray) {
31-
hint::black_box(boolean_kernels::and(lhs, rhs).unwrap());
35+
for _ in 0..RUNS_PER_SAMPLE {
36+
hint::black_box(boolean_kernels::and(lhs, rhs).unwrap());
37+
}
3238
}
3339

3440
fn bench_or(lhs: &BooleanArray, rhs: &BooleanArray) {
35-
hint::black_box(boolean_kernels::or(lhs, rhs).unwrap());
41+
for _ in 0..RUNS_PER_SAMPLE {
42+
hint::black_box(boolean_kernels::or(lhs, rhs).unwrap());
43+
}
3644
}
3745

3846
fn bench_not(array: &BooleanArray) {
39-
hint::black_box(boolean_kernels::not(array).unwrap());
47+
for _ in 0..RUNS_PER_SAMPLE {
48+
hint::black_box(boolean_kernels::not(array).unwrap());
49+
}
4050
}
4151

4252
fn add_benchmark(c: &mut Criterion) {
43-
let size = 2usize.pow(15);
44-
let array1 = create_boolean_array(size, 0.0, 0.5);
45-
let array2 = create_boolean_array(size, 0.0, 0.5);
53+
let array1_full = create_boolean_array(ARRAY_LEN + 1, 0.0, 0.5);
54+
let array2_full = create_boolean_array(ARRAY_LEN + 1, 0.0, 0.5);
55+
let array1 = array1_full.slice(0, ARRAY_LEN);
56+
let array2 = array2_full.slice(0, ARRAY_LEN);
4657
c.bench_function("and", |b| b.iter(|| bench_and(&array1, &array2)));
4758
c.bench_function("or", |b| b.iter(|| bench_or(&array1, &array2)));
4859
c.bench_function("not", |b| b.iter(|| bench_not(&array1)));
4960

50-
let array1_slice = array1.slice(1, size - 1);
51-
let array1_slice = array1_slice
52-
.as_any()
53-
.downcast_ref::<BooleanArray>()
54-
.unwrap();
55-
let array2_slice = array2.slice(1, size - 1);
56-
let array2_slice = array2_slice
57-
.as_any()
58-
.downcast_ref::<BooleanArray>()
59-
.unwrap();
61+
let array1_slice = array1_full.slice(1, ARRAY_LEN);
62+
let array2_slice = array2_full.slice(1, ARRAY_LEN);
6063

6164
c.bench_function("and_sliced", |b| {
62-
b.iter(|| bench_and(array1_slice, array2_slice))
65+
b.iter(|| bench_and(&array1_slice, &array2_slice))
6366
});
6467
c.bench_function("or_sliced", |b| {
65-
b.iter(|| bench_or(array1_slice, array2_slice))
68+
b.iter(|| bench_or(&array1_slice, &array2_slice))
6669
});
67-
c.bench_function("not_sliced", |b| b.iter(|| bench_not(array1_slice)));
70+
c.bench_function("not_sliced", |b| b.iter(|| bench_not(&array1_slice)));
6871
}
6972

7073
criterion_group!(benches, add_benchmark);

0 commit comments

Comments
 (0)