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
8 changes: 8 additions & 0 deletions encodings/runend/src/trace_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,14 @@ fn trace_compare_on_runend() -> VortexResult<()> {
iter 0 current=vortex.runend(bool, len=9) builder_active=false
execute_until target=AnyCanonical root=vortex.binary(bool, len=3)
iter 0 current=vortex.binary(bool, len=3) builder_active=false
optimize root=vortex.slice(i32, len=1) session=false
reduce_parent static:SliceReduceAdaptor(Constant) slot=0 parent=vortex.slice(i32, len=1) child=vortex.constant(i32, len=3) -> vortex.constant(i32, len=1)
done output=vortex.constant(i32, len=1)
execute_until target=AnyCanonical root=vortex.constant(i32, len=1)
iter 0 current=vortex.constant(i32, len=1) builder_active=false
Done array=vortex.primitive(i32, len=1)
iter 1 current=vortex.primitive(i32, len=1) builder_active=false
return output=vortex.primitive(i32, len=1)
Done array=vortex.bool(bool, len=3)
iter 1 current=vortex.bool(bool, len=3) builder_active=false
return output=vortex.bool(bool, len=3)
Expand Down
115 changes: 115 additions & 0 deletions vortex-array/benches/compare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#![expect(clippy::unwrap_used)]

use divan::Bencher;
use divan::counter::ItemsCount;
use mimalloc::MiMalloc;
use rand::RngExt;
use rand::SeedableRng;
Expand Down Expand Up @@ -38,6 +39,7 @@ const ARRAY_SIZE: usize = 65_536;
fn bench_compare(bencher: Bencher, lhs: ArrayRef, rhs: ArrayRef, op: Operator) {
let session = vortex_array::array_session();
bencher
.counter(ItemsCount::new(ARRAY_SIZE))
.with_inputs(|| (&lhs, &rhs, session.create_execution_ctx()))
.bench_refs(|input| {
input
Expand All @@ -49,6 +51,31 @@ fn bench_compare(bencher: Bencher, lhs: ArrayRef, rhs: ArrayRef, op: Operator) {
});
}

fn u8_array(offset: u8) -> ArrayRef {
(0u8..=u8::MAX)
.cycle()
.take(ARRAY_SIZE)
.map(|value| value.wrapping_add(offset))
.collect::<Buffer<_>>()
.into_array()
}

fn i32_array(offset: i32) -> ArrayRef {
(0i32..)
.take(ARRAY_SIZE)
.map(|value| value.wrapping_mul(31).wrapping_add(offset))
.collect::<Buffer<_>>()
.into_array()
}

fn u64_array(offset: u64) -> ArrayRef {
(0u64..)
.take(ARRAY_SIZE)
.map(|value| value.wrapping_mul(31).wrapping_add(offset))
.collect::<Buffer<_>>()
.into_array()
}

fn bool_array(rng: &mut StdRng) -> ArrayRef {
BoolArray::from_iter((0..ARRAY_SIZE).map(|_| rng.random_bool(0.5))).into_array()
}
Expand Down Expand Up @@ -87,6 +114,13 @@ fn float_array(rng: &mut StdRng) -> ArrayRef {
.into_array()
}

fn f32_array(rng: &mut StdRng) -> ArrayRef {
(0..ARRAY_SIZE)
.map(|_| rng.random_range(0.0f32..1.0))
.collect::<Buffer<_>>()
.into_array()
}

fn string_array(rng: &mut StdRng) -> ArrayRef {
VarBinViewArray::from_iter_str((0..ARRAY_SIZE).map(|_| {
let len = rng.random_range(1usize..24);
Expand Down Expand Up @@ -153,6 +187,14 @@ fn compare_int_constant(bencher: Bencher) {
bench_compare(bencher, arr, constant, Operator::Gte);
}

#[divan::bench]
fn compare_int_constant_lhs(bencher: Bencher) {
let mut rng = StdRng::seed_from_u64(0);
let constant = ConstantArray::new(50_000_000i64, ARRAY_SIZE).into_array();
let arr = int_array(&mut rng);
bench_compare(bencher, constant, arr, Operator::Gte);
}

#[divan::bench]
fn compare_int_eq(bencher: Bencher) {
let mut rng = StdRng::seed_from_u64(0);
Expand All @@ -161,6 +203,55 @@ fn compare_int_eq(bencher: Bencher) {
bench_compare(bencher, arr1, arr2, Operator::Eq);
}

#[divan::bench]
fn compare_i32(bencher: Bencher) {
let lhs = i32_array(1);
let rhs = i32_array(17);
bench_compare(bencher, lhs, rhs, Operator::Gte);
}

#[divan::bench]
fn compare_i32_constant(bencher: Bencher) {
let lhs = i32_array(1);
let rhs = ConstantArray::new(1_000_000i32, ARRAY_SIZE).into_array();
bench_compare(bencher, lhs, rhs, Operator::Gte);
}

#[divan::bench]
fn compare_u8(bencher: Bencher) {
let lhs = u8_array(1);
let rhs = u8_array(17);
bench_compare(bencher, lhs, rhs, Operator::Gte);
}

#[divan::bench]
fn compare_u8_constant(bencher: Bencher) {
let lhs = u8_array(1);
let rhs = ConstantArray::new(127u8, ARRAY_SIZE).into_array();
bench_compare(bencher, lhs, rhs, Operator::Gte);
}

#[divan::bench]
fn compare_u64(bencher: Bencher) {
let lhs = u64_array(1);
let rhs = u64_array(17);
bench_compare(bencher, lhs, rhs, Operator::Gte);
}

#[divan::bench]
fn compare_u64_constant(bencher: Bencher) {
let lhs = u64_array(1);
let rhs = ConstantArray::new(1_000_000u64, ARRAY_SIZE).into_array();
bench_compare(bencher, lhs, rhs, Operator::Gte);
}

#[divan::bench]
fn compare_u64_eq(bencher: Bencher) {
let lhs = u64_array(1);
let rhs = u64_array(17);
bench_compare(bencher, lhs, rhs, Operator::Eq);
}

#[divan::bench]
fn compare_float(bencher: Bencher) {
let mut rng = StdRng::seed_from_u64(0);
Expand All @@ -169,6 +260,30 @@ fn compare_float(bencher: Bencher) {
bench_compare(bencher, arr1, arr2, Operator::Gte);
}

#[divan::bench]
fn compare_float_eq(bencher: Bencher) {
let mut rng = StdRng::seed_from_u64(0);
let arr1 = float_array(&mut rng);
let arr2 = float_array(&mut rng);
bench_compare(bencher, arr1, arr2, Operator::Eq);
}

#[divan::bench]
fn compare_f32(bencher: Bencher) {
let mut rng = StdRng::seed_from_u64(0);
let arr1 = f32_array(&mut rng);
let arr2 = f32_array(&mut rng);
bench_compare(bencher, arr1, arr2, Operator::Gte);
}

#[divan::bench]
fn compare_f32_eq(bencher: Bencher) {
let mut rng = StdRng::seed_from_u64(0);
let arr1 = f32_array(&mut rng);
let arr2 = f32_array(&mut rng);
bench_compare(bencher, arr1, arr2, Operator::Eq);
}

#[divan::bench]
fn compare_decimal(bencher: Bencher) {
let mut rng = StdRng::seed_from_u64(0);
Expand Down
8 changes: 4 additions & 4 deletions vortex-array/src/scalar_fn/fns/binary/compare/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
//! Native comparison kernels.
//!
//! [`execute_compare`] dispatches on the logical [`DType`] of its operands and evaluates every
//! comparison directly over Vortex canonical arraysbit buffers for booleans, lane kernels from
//! `vortex-compute` for primitives and decimals, binary views for strings/bytes, and a row-wise
//! comparator for nested types. There is no Arrow fallback.
//! comparison directly over Vortex canonical arrays: bit buffers for booleans, row or fused lane
//! kernels for primitives, lane kernels for decimals, binary views for strings and bytes, and a
//! row-wise comparator for nested types. There is no Arrow fallback.
//!
//! Floating point values compare with Vortex's total ordering (`NaN` is the largest value,
//! `-0.0 < +0.0`, and equality is bitwise), matching [`Scalar`] comparison semantics.
Expand Down Expand Up @@ -211,7 +211,7 @@ fn compare_arrays(
)
.into_array()),
DType::Bool(_) => boolean::compare_bool(lhs, rhs, op, nullability, ctx),
DType::Primitive(..) => primitive::compare_primitive(lhs, rhs, op, nullability, ctx),
DType::Primitive(..) => primitive::compare_primitive(lhs, rhs, op, ctx),
DType::Decimal(..) => decimal::compare_decimal(lhs, rhs, op, nullability, ctx),
DType::Utf8(_) | DType::Binary(_) => bytes::compare_bytes(lhs, rhs, op, nullability, ctx),
DType::Struct(..) | DType::List(..) | DType::FixedSizeList(..) | DType::Map(..) => {
Expand Down
Loading
Loading