Skip to content
Merged
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
6 changes: 0 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

35 changes: 2 additions & 33 deletions encodings/fastlanes/benches/bitpack_compare.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: Copyright the Vortex contributors

//! Compare an already-packed `BitPackedArray` against a constant value. Compares the
//! out-of-range fast path (constant outside `[0, 2^bit_width - 1]`) against an explicit
//! "decompress, then compare" baseline.
//! Compare an already-packed `BitPackedArray` against a constant outside
//! `[0, 2^bit_width - 1]`, which the bit width alone decides without unpacking.
//!
//! Sized to finish quickly. Run with `cargo bench -p vortex-fastlanes --bench bitpack_compare`.

Expand Down Expand Up @@ -115,22 +114,6 @@ fn fast_eq_out_of_range(bencher: Bencher) {
});
}

#[divan::bench]
fn baseline_eq(bencher: Bencher) {
let (array, rhs, mut ctx) = build_inputs();
bencher.bench_local(|| {
// What the fallback would do: materialize the unpacked primitive, then run Arrow
// compare on it.
let primitive = array.clone().execute::<PrimitiveArray>(&mut ctx).unwrap();
primitive
.into_array()
.binary(rhs.clone(), Operator::Eq)
.unwrap()
.execute::<BoolArray>(&mut ctx)
.unwrap()
});
}

#[divan::bench]
fn fast_lt_out_of_range(bencher: Bencher) {
let (array, rhs, mut ctx) = build_inputs();
Expand All @@ -143,17 +126,3 @@ fn fast_lt_out_of_range(bencher: Bencher) {
.unwrap()
});
}

#[divan::bench]
fn baseline_lt(bencher: Bencher) {
let (array, rhs, mut ctx) = build_inputs();
bencher.bench_local(|| {
let primitive = array.clone().execute::<PrimitiveArray>(&mut ctx).unwrap();
primitive
.into_array()
.binary(rhs.clone(), Operator::Lt)
.unwrap()
.execute::<BoolArray>(&mut ctx)
.unwrap()
});
}
47 changes: 7 additions & 40 deletions encodings/fastlanes/benches/bitpacking_take.rs
Original file line number Diff line number Diff line change
Expand Up @@ -429,8 +429,7 @@ fn patched_take_10k_adversarial(bencher: Bencher) {
})
}

// These are the element runs emitted by a sparse FSL gather. The baseline materializes those
// runs inside the measured operation, reproducing the previous BitPacked take path.
// These are the element runs emitted by a sparse FSL gather.
fn embedding_runs_fixture(dimension: usize, ptype: PType, bit_width: u8) -> (ArrayRef, ArrayRef) {
const ROWS: usize = 512;
const SELECTED: usize = 16;
Expand Down Expand Up @@ -464,25 +463,13 @@ fn embedding_runs_fixture(dimension: usize, ptype: PType, bit_width: u8) -> (Arr
#[divan::bench(args = [768, 1024, 1536])]
fn embedding_runs(bencher: Bencher, dimension: usize) {
let (packed, indices) = embedding_runs_fixture(dimension, PType::U32, 16);
bench_piecewise_take(bencher, packed, indices, false);
}

#[divan::bench(args = [768, 1024, 1536])]
fn embedding_runs_expanded_baseline(bencher: Bencher, dimension: usize) {
let (packed, indices) = embedding_runs_fixture(dimension, PType::U32, 16);
bench_piecewise_take(bencher, packed, indices, true);
bench_piecewise_take(bencher, packed, indices);
}

#[divan::bench(args = [512, 1024, 2048, 4096])]
fn embedding_code_runs(bencher: Bencher, dimension: usize) {
let (packed, indices) = embedding_runs_fixture(dimension, PType::U8, 4);
bench_piecewise_take(bencher, packed, indices, false);
}

#[divan::bench(args = [512, 1024, 2048, 4096])]
fn embedding_code_runs_expanded_baseline(bencher: Bencher, dimension: usize) {
let (packed, indices) = embedding_runs_fixture(dimension, PType::U8, 4);
bench_piecewise_take(bencher, packed, indices, true);
bench_piecewise_take(bencher, packed, indices);
}

// Short runs share chunks; long runs visit distant chunks. Neither crosses the full-decode
Expand Down Expand Up @@ -514,13 +501,7 @@ fn fragmented_runs_fixture(run_length: usize) -> (ArrayRef, ArrayRef) {
#[divan::bench(args = [1, 2, 7, 8, 64, 512, 1024])]
fn fragmented_runs(bencher: Bencher, run_length: usize) {
let (packed, indices) = fragmented_runs_fixture(run_length);
bench_piecewise_take(bencher, packed, indices, false);
}

#[divan::bench(args = [1, 2, 7, 8, 64, 512, 1024])]
fn fragmented_runs_expanded_baseline(bencher: Bencher, run_length: usize) {
let (packed, indices) = fragmented_runs_fixture(run_length);
bench_piecewise_take(bencher, packed, indices, true);
bench_piecewise_take(bencher, packed, indices);
}

// Isolated runs cannot amortize a whole-chunk decode across neighboring runs. Offsets near
Expand Down Expand Up @@ -565,30 +546,16 @@ fn isolated_runs<T: NativePType>(bencher: Bencher, (run_length, offset): (usize,
)
.unwrap()
.into_array();
bench_piecewise_take(bencher, packed, indices, false);
bench_piecewise_take(bencher, packed, indices);
}

fn bench_piecewise_take(
bencher: Bencher,
packed: ArrayRef,
indices: ArrayRef,
expanded_baseline: bool,
) {
fn bench_piecewise_take(bencher: Bencher, packed: ArrayRef, indices: ArrayRef) {
bencher
.counter(ItemsCount::new(indices.len()))
.with_inputs(|| (indices.clone(), SESSION.create_execution_ctx()))
.bench_refs(|(indices, ctx)| {
let indices = if expanded_baseline {
indices
.clone()
.execute::<PrimitiveArray>(ctx)
.unwrap()
.into_array()
} else {
indices.clone()
};
packed
.take(indices)
.take(indices.clone())
.unwrap()
.execute::<RecursiveCanonical>(ctx)
.unwrap()
Expand Down
20 changes: 10 additions & 10 deletions scripts/codspeed_bench_counts.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"expr_large_struct_pack": 4,
"expr_optimize": 1,
"filter_bool": 61,
"filter_fixed_width": 31,
"filter_fixed_width": 30,
"filter_fsl": 4,
"filter_list": 12,
"interleave": 18,
Expand All @@ -43,7 +43,7 @@
"listview_rebuild": 9,
"listview_zip": 2,
"patches_lookup": 10,
"piecewise_sequence_take_primitive": 15,
"piecewise_sequence_take_primitive": 10,
"primitive_zip": 2,
"probe": 6,
"row_fn_bool_retry": 0,
Expand All @@ -60,7 +60,7 @@
"scalar_construction": 10,
"scalar_fn_probe": 8,
"scalar_subtract": 0,
"search_sorted": 2,
"search_sorted": 1,
"slice_dict_primitive": 3,
"take_chunked": 27,
"take_filter": 32,
Expand All @@ -74,16 +74,16 @@
"varbinview_fill_null": 2,
"varbinview_try_new": 6,
"varbinview_zip": 2,
"widen": 46,
"widen": 17,
"widen_decimal": 6
},
"vortex-buffer": {
"allocation": 35,
"collect_bool": 4,
"cpu_dispatch": 6,
"take_bits": 0,
"vortex_bitbuffer": 101,
"vortex_buffer": 40
"vortex_bitbuffer": 58,
"vortex_buffer": 34
},
"vortex-compressor": {
"dict_encode": 0,
Expand All @@ -92,7 +92,7 @@
"stats_calc": 0
},
"vortex-compute": {
"lane_kernels": 10
"lane_kernels": 7
},
"vortex-datetime-parts": {
"split_temporal": 4
Expand All @@ -108,10 +108,10 @@
"vortex-fastlanes": {
"bitpack_blocked": 0,
"bitpack_blocked_decompress": 0,
"bitpack_compare": 4,
"bitpack_compare": 2,
"bitpack_compare_sweep": 232,
"bitpacking_filter": 0,
"bitpacking_take": 54,
"bitpacking_take": 40,
"canonicalize_bench": 32,
"cast_bitpacked": 6,
"compute_between": 33,
Expand Down Expand Up @@ -144,7 +144,7 @@
"scalar": 4
},
"vortex-row": {
"row_encode": 10
"row_encode": 5
},
"vortex-sparse": {
"sparse_canonical": 4,
Expand Down
4 changes: 1 addition & 3 deletions vortex-array/benches/filter_fixed_width.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,11 @@ const CACHED_DENSITIES: &[f64] = &[0.01, 0.1];

#[derive(Clone, Copy, Debug)]
enum Pattern {
Random,
Runs,
Contiguous,
}

const PATTERNS: &[Pattern] = &[Pattern::Random, Pattern::Runs, Pattern::Contiguous];
const PATTERNS: &[Pattern] = &[Pattern::Runs, Pattern::Contiguous];

fn random_mask(len: usize, density: f64) -> Mask {
let threshold = (density * u64::MAX as f64) as u64;
Expand All @@ -82,7 +81,6 @@ fn random_mask(len: usize, density: f64) -> Mask {

fn pattern_mask(len: usize, pattern: Pattern) -> Mask {
match pattern {
Pattern::Random => random_mask(len, 0.5),
Pattern::Runs => Mask::from_iter((0..len).map(|index| (index / 32).is_multiple_of(2))),
Pattern::Contiguous => Mask::from_slices(len, vec![(len / 4, len * 3 / 4)]),
}
Expand Down
53 changes: 0 additions & 53 deletions vortex-array/benches/piecewise_sequence_take_primitive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@
// SPDX-FileCopyrightText: Copyright the Vortex contributors

//! Primitive take benchmarks for [`PiecewiseSequenceArray`] length representations.
//!
//! The `reify_constant_lengths_then_take` case simulates removing the constant-length
//! specialization: it starts with constant lengths, materializes them to a dense primitive array,
//! and then executes the primitive take through the non-constant-length path.

#![allow(clippy::cast_possible_truncation)]
#![expect(clippy::unwrap_used)]
Expand Down Expand Up @@ -89,55 +85,6 @@ fn prebuilt_dense_lengths(bencher: Bencher, run_length: usize) {
});
}

#[divan::bench(args = RUN_LENGTHS)]
fn reify_constant_lengths_then_take(bencher: Bencher, run_length: usize) {
let values = values();
let run_count = run_count(run_length);
let starts = starts(run_count, run_length).into_array();
let lengths = lengths_constant(run_length, run_count);
let multipliers = ConstantArray::new(1u64, run_count).into_array();

bencher
.counter(BytesCount::of_many::<i64>(OUTPUT_LEN))
.with_inputs(|| {
(
&values,
starts.clone(),
lengths.clone(),
multipliers.clone(),
SESSION.create_execution_ctx(),
)
})
.bench_refs(|(values, starts, lengths, multipliers, ctx)| {
let lengths = lengths
.clone()
.execute::<PrimitiveArray>(ctx)
.unwrap()
.into_array();

// SAFETY: starts, reified lengths, and unit multipliers have the same run count, are
// non-null unsigned integer arrays, and expand to OUTPUT_LEN by construction.
let indices = unsafe {
PiecewiseSequenceArray::new_unchecked(
starts.clone(),
lengths,
multipliers.clone(),
OUTPUT_LEN,
)
}
.into_array();

divan::black_box(
values
.clone()
.take(indices)
.unwrap()
.execute::<PrimitiveArray>(ctx)
.unwrap(),
);
});
}

fn values() -> ArrayRef {
PrimitiveArray::from_iter((0..SOURCE_LEN).map(|idx| idx as i64)).into_array()
}
Expand Down
19 changes: 2 additions & 17 deletions vortex-array/benches/search_sorted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,10 @@ fn main() {
}

/// One search over 65536 elements is ~16 comparisons, small enough that the measurement is mostly
/// harness overhead and the two implementations below become indistinguishable. Search a batch per
/// iteration instead; the targets differ, so the calls cannot be folded together.
/// harness overhead. Search a batch per iteration instead; the targets differ, so the calls cannot
/// be folded together.
const SEARCH_TARGETS: usize = 64;

#[cfg(not(codspeed))]
#[divan::bench]
fn binary_search_std(bencher: Bencher) {
let (sorted_array, targets) = fixture();
bencher
.with_inputs(|| (&sorted_array, &targets))
.bench_refs(|(array, targets)| {
let mut found = 0;
for target in targets.iter() {
found += array.binary_search(target).unwrap_or_else(|idx| idx);
}
found
});
}

#[divan::bench]
fn binary_search_vortex(bencher: Bencher) {
let (sorted_array, targets) = fixture();
Expand Down
Loading
Loading