diff --git a/Cargo.lock b/Cargo.lock index 0010a4e6cec..2508ba7a3e8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9631,6 +9631,7 @@ dependencies = [ "uuid", "vortex-array", "vortex-array-macros", + "vortex-bench-support", "vortex-buffer", "vortex-compute", "vortex-error", diff --git a/vortex-array/Cargo.toml b/vortex-array/Cargo.toml index 7c5936627e5..16f2db98554 100644 --- a/vortex-array/Cargo.toml +++ b/vortex-array/Cargo.toml @@ -97,6 +97,7 @@ vortex-array = { path = ".", features = [ "table-display", "unstable_row_fns", ] } +vortex-bench-support = { workspace = true } [[bench]] name = "aggregate_max" diff --git a/vortex-array/benches/take_primitive.rs b/vortex-array/benches/take_primitive.rs index c030c976e97..a3787d55a0d 100644 --- a/vortex-array/benches/take_primitive.rs +++ b/vortex-array/benches/take_primitive.rs @@ -29,6 +29,9 @@ fn main() { /// Number of indices to take. The top tier is sized to keep CodSpeed simulation under 1ms. const NUM_INDICES: &[usize] = &[1_000, 10_000, 25_000]; +/// Large enough to measure both cache-resident and streaming dictionary decoding. +const GT_NUM_INDICES: &[usize] = &[1_000_000, 16_000_000]; + /// Size of the source vector / dictionary values. const VECTOR_SIZE: &[usize] = &[16, 256, 2048, 8192]; @@ -90,3 +93,28 @@ fn dict_canonicalize_zipfian(bencher: Bencher, num_indi .with_inputs(|| (&dict, SESSION.create_execution_ctx())) .bench_refs(|(dict, ctx)| (*dict).clone().into_array().execute::(ctx)); } + +/// StatPopGen GT distribution: 75.21% 0, 3.85% 1, 0.45% 2, and 20.49% null. +#[vortex_bench_support::cpu_features] +#[divan::bench(args = GT_NUM_INDICES)] +fn dict_canonicalize_gt_u8(bencher: Bencher, num_indices: usize) { + let values = PrimitiveArray::from_option_iter([Some(0u8), Some(1), Some(2), None]); + let range = Uniform::new(0u16, 10_000).unwrap(); + let codes = PrimitiveArray::from_iter( + StdRng::seed_from_u64(0) + .sample_iter(range) + .take(num_indices) + .map(|sample| match sample { + 0..7521 => 0u8, + 7521..7906 => 1, + 7906..7951 => 2, + _ => 3, + }), + ); + let dict = DictArray::try_new(codes.into_array(), values.into_array()).unwrap(); + + bencher + .counter(ItemsCount::new(num_indices)) + .with_inputs(|| (&dict, SESSION.create_execution_ctx())) + .bench_refs(|(dict, ctx)| (*dict).clone().into_array().execute::(ctx)); +}