Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 82 additions & 22 deletions arrow/benches/bitwise_kernel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,80 +32,140 @@ extern crate arrow;
use arrow::util::bench_util::create_primitive_array;
use arrow::util::test_util::seedable_rng;

const ARRAY_LEN: usize = 8_192;

// These bitwise kernels are very cheap, so run them many times per Criterion iteration to
// try and reduce noise in the benchmarks.
const RUNS_PER_SAMPLE: usize = 100;

fn bitwise_array_benchmark(c: &mut Criterion) {
let size = 64 * 1024_usize;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We often run these kernels on 8k elements, not 64k elements, so adjust the benchmark to reflect that

let left_without_null = create_primitive_array::<Int64Type>(size, 0 as f32);
let right_without_null = create_primitive_array::<Int64Type>(size, 0 as f32);
let left_with_null = create_primitive_array::<Int64Type>(size, 0.2_f32);
let right_with_null = create_primitive_array::<Int64Type>(size, 0.2_f32);
let left_without_null = create_primitive_array::<Int64Type>(ARRAY_LEN, 0 as f32);
let right_without_null = create_primitive_array::<Int64Type>(ARRAY_LEN, 0 as f32);
let left_with_null = create_primitive_array::<Int64Type>(ARRAY_LEN, 0.2_f32);
let right_with_null = create_primitive_array::<Int64Type>(ARRAY_LEN, 0.2_f32);
// array and
let mut group = c.benchmark_group("bench bitwise array: and");
group.bench_function("bitwise array and, no nulls", |b| {
b.iter(|| hint::black_box(bitwise_and(&left_without_null, &right_without_null).unwrap()))
b.iter(|| {
for _ in 0..RUNS_PER_SAMPLE {
hint::black_box(bitwise_and(&left_without_null, &right_without_null).unwrap());
}
})
});
group.bench_function("bitwise array and, 20% nulls", |b| {
b.iter(|| hint::black_box(bitwise_and(&left_with_null, &right_with_null).unwrap()))
b.iter(|| {
for _ in 0..RUNS_PER_SAMPLE {
hint::black_box(bitwise_and(&left_with_null, &right_with_null).unwrap());
}
})
});
group.finish();
// array or
let mut group = c.benchmark_group("bench bitwise: or");
group.bench_function("bitwise array or, no nulls", |b| {
b.iter(|| hint::black_box(bitwise_or(&left_without_null, &right_without_null).unwrap()))
b.iter(|| {
for _ in 0..RUNS_PER_SAMPLE {
hint::black_box(bitwise_or(&left_without_null, &right_without_null).unwrap());
}
})
});
group.bench_function("bitwise array or, 20% nulls", |b| {
b.iter(|| hint::black_box(bitwise_or(&left_with_null, &right_with_null).unwrap()))
b.iter(|| {
for _ in 0..RUNS_PER_SAMPLE {
hint::black_box(bitwise_or(&left_with_null, &right_with_null).unwrap());
}
})
});
group.finish();
// xor
let mut group = c.benchmark_group("bench bitwise: xor");
group.bench_function("bitwise array xor, no nulls", |b| {
b.iter(|| hint::black_box(bitwise_xor(&left_without_null, &right_without_null).unwrap()))
b.iter(|| {
for _ in 0..RUNS_PER_SAMPLE {
hint::black_box(bitwise_xor(&left_without_null, &right_without_null).unwrap());
}
})
});
group.bench_function("bitwise array xor, 20% nulls", |b| {
b.iter(|| hint::black_box(bitwise_xor(&left_with_null, &right_with_null).unwrap()))
b.iter(|| {
for _ in 0..RUNS_PER_SAMPLE {
hint::black_box(bitwise_xor(&left_with_null, &right_with_null).unwrap());
}
})
});
group.finish();
// not
let mut group = c.benchmark_group("bench bitwise: not");
group.bench_function("bitwise array not, no nulls", |b| {
b.iter(|| hint::black_box(bitwise_not(&left_without_null).unwrap()))
b.iter(|| {
for _ in 0..RUNS_PER_SAMPLE {
hint::black_box(bitwise_not(&left_without_null).unwrap());
}
});
});
group.bench_function("bitwise array not, 20% nulls", |b| {
b.iter(|| hint::black_box(bitwise_not(&left_with_null).unwrap()))
b.iter(|| {
for _ in 0..RUNS_PER_SAMPLE {
hint::black_box(bitwise_not(&left_with_null).unwrap());
}
});
});
group.finish();
}

fn bitwise_array_scalar_benchmark(c: &mut Criterion) {
let size = 64 * 1024_usize;
let array_without_null = create_primitive_array::<Int64Type>(size, 0 as f32);
let array_with_null = create_primitive_array::<Int64Type>(size, 0.2_f32);
let array_without_null = create_primitive_array::<Int64Type>(ARRAY_LEN, 0 as f32);
let array_with_null = create_primitive_array::<Int64Type>(ARRAY_LEN, 0.2_f32);
let scalar = seedable_rng().next_u64() as i64;
// array scalar and
let mut group = c.benchmark_group("bench bitwise array scalar: and");
group.bench_function("bitwise array scalar and, no nulls", |b| {
b.iter(|| hint::black_box(bitwise_and_scalar(&array_without_null, scalar).unwrap()))
b.iter(|| {
for _ in 0..RUNS_PER_SAMPLE {
hint::black_box(bitwise_and_scalar(&array_without_null, scalar).unwrap());
}
})
});
group.bench_function("bitwise array and, 20% nulls", |b| {
b.iter(|| hint::black_box(bitwise_and_scalar(&array_with_null, scalar).unwrap()))
b.iter(|| {
for _ in 0..RUNS_PER_SAMPLE {
hint::black_box(bitwise_and_scalar(&array_with_null, scalar).unwrap());
}
})
});
group.finish();
// array scalar or
let mut group = c.benchmark_group("bench bitwise array scalar: or");
group.bench_function("bitwise array scalar or, no nulls", |b| {
b.iter(|| hint::black_box(bitwise_or_scalar(&array_without_null, scalar).unwrap()))
b.iter(|| {
for _ in 0..RUNS_PER_SAMPLE {
hint::black_box(bitwise_or_scalar(&array_without_null, scalar).unwrap());
}
})
});
group.bench_function("bitwise array scalar or, 20% nulls", |b| {
b.iter(|| hint::black_box(bitwise_or_scalar(&array_with_null, scalar).unwrap()))
b.iter(|| {
for _ in 0..RUNS_PER_SAMPLE {
hint::black_box(bitwise_or_scalar(&array_with_null, scalar).unwrap());
}
})
});
group.finish();
// array scalar xor
let mut group = c.benchmark_group("bench bitwise array scalar: xor");
group.bench_function("bitwise array scalar xor, no nulls", |b| {
b.iter(|| hint::black_box(bitwise_xor_scalar(&array_without_null, scalar).unwrap()))
b.iter(|| {
for _ in 0..RUNS_PER_SAMPLE {
hint::black_box(bitwise_xor_scalar(&array_without_null, scalar).unwrap());
}
})
});
group.bench_function("bitwise array scalar xor, 20% nulls", |b| {
b.iter(|| hint::black_box(bitwise_xor_scalar(&array_with_null, scalar).unwrap()))
b.iter(|| {
for _ in 0..RUNS_PER_SAMPLE {
hint::black_box(bitwise_xor_scalar(&array_with_null, scalar).unwrap());
}
})
});
group.finish();
}
Expand Down
42 changes: 23 additions & 19 deletions arrow/benches/boolean_kernels.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,44 +27,48 @@ use arrow::array::*;
use arrow::compute::kernels::boolean as boolean_kernels;
use std::hint;

const ARRAY_LEN: usize = 8_192;
// These bitwise kernels are very cheap, so run them many times per Criterion iteration to
// try and reduce noise in the benchmarks.
const RUNS_PER_SAMPLE: usize = 100;

fn bench_and(lhs: &BooleanArray, rhs: &BooleanArray) {
hint::black_box(boolean_kernels::and(lhs, rhs).unwrap());
for _ in 0..RUNS_PER_SAMPLE {
hint::black_box(boolean_kernels::and(lhs, rhs).unwrap());
}
}

fn bench_or(lhs: &BooleanArray, rhs: &BooleanArray) {
hint::black_box(boolean_kernels::or(lhs, rhs).unwrap());
for _ in 0..RUNS_PER_SAMPLE {
hint::black_box(boolean_kernels::or(lhs, rhs).unwrap());
}
}

fn bench_not(array: &BooleanArray) {
hint::black_box(boolean_kernels::not(array).unwrap());
for _ in 0..RUNS_PER_SAMPLE {
hint::black_box(boolean_kernels::not(array).unwrap());
}
}

fn add_benchmark(c: &mut Criterion) {
let size = 2usize.pow(15);
let array1 = create_boolean_array(size, 0.0, 0.5);
let array2 = create_boolean_array(size, 0.0, 0.5);
let array1_full = create_boolean_array(ARRAY_LEN + 1, 0.0, 0.5);
let array2_full = create_boolean_array(ARRAY_LEN + 1, 0.0, 0.5);
let array1 = array1_full.slice(0, ARRAY_LEN);
let array2 = array2_full.slice(0, ARRAY_LEN);
c.bench_function("and", |b| b.iter(|| bench_and(&array1, &array2)));
c.bench_function("or", |b| b.iter(|| bench_or(&array1, &array2)));
c.bench_function("not", |b| b.iter(|| bench_not(&array1)));

let array1_slice = array1.slice(1, size - 1);
let array1_slice = array1_slice
.as_any()
.downcast_ref::<BooleanArray>()
.unwrap();
let array2_slice = array2.slice(1, size - 1);
let array2_slice = array2_slice
.as_any()
.downcast_ref::<BooleanArray>()
.unwrap();
let array1_slice = array1_full.slice(1, ARRAY_LEN);
let array2_slice = array2_full.slice(1, ARRAY_LEN);

c.bench_function("and_sliced", |b| {
b.iter(|| bench_and(array1_slice, array2_slice))
b.iter(|| bench_and(&array1_slice, &array2_slice))
});
c.bench_function("or_sliced", |b| {
b.iter(|| bench_or(array1_slice, array2_slice))
b.iter(|| bench_or(&array1_slice, &array2_slice))
});
c.bench_function("not_sliced", |b| b.iter(|| bench_not(array1_slice)));
c.bench_function("not_sliced", |b| b.iter(|| bench_not(&array1_slice)));
}

criterion_group!(benches, add_benchmark);
Expand Down
Loading