Skip to content

Commit 4daa1f0

Browse files
simplify DataGeneratorFn
1 parent c4c8b99 commit 4daa1f0

1 file changed

Lines changed: 63 additions & 32 deletions

File tree

benches/fastpfor_benchmark.rs

Lines changed: 63 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use core::ops::Range;
12
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Throughput};
23
use fastpfor::rust::{FastPFOR, Integer, BLOCK_SIZE_128, BLOCK_SIZE_256, DEFAULT_PAGE_SIZE};
34
use rand::rngs::StdRng;
@@ -8,15 +9,27 @@ use std::io::Cursor;
89
const SIZES: &[usize; 2] = &[1024, 4096];
910
const SEED: u64 = 456;
1011

12+
type DataGeneratorFn = fn(usize) -> Vec<u32>;
13+
1114
/// Generate uniformly distributed random data
12-
fn generate_uniform_data(size: usize, max_value: u32) -> Vec<u32> {
13-
let mut rng = StdRng::seed_from_u64(black_box(SEED));
14-
(0..size).map(|_| rng.random_range(0..max_value)).collect()
15+
fn generate_uniform_data_from_range(size: usize, value_range: Range<u32>) -> Vec<u32> {
16+
let mut rng = StdRng::seed_from_u64(SEED);
17+
(0..size)
18+
.map(|_| rng.random_range(value_range.clone()))
19+
.collect()
20+
}
21+
22+
fn generate_uniform_data_small_value_distribution(size: usize) -> Vec<u32> {
23+
generate_uniform_data_from_range(size, 0..1000)
24+
}
25+
26+
fn generate_uniform_data_large_value_distribution(size: usize) -> Vec<u32> {
27+
generate_uniform_data_from_range(size, 0..u32::MAX)
1528
}
1629

1730
/// Generate clustered data - values tend to cluster around changing base values
1831
fn generate_clustered_data(size: usize) -> Vec<u32> {
19-
let mut rng = StdRng::seed_from_u64(black_box(SEED));
32+
let mut rng = StdRng::seed_from_u64(SEED);
2033
let mut data = Vec::with_capacity(size);
2134
let mut base = 0u32;
2235

@@ -37,7 +50,7 @@ fn generate_sequential_data(size: usize) -> Vec<u32> {
3750

3851
/// Generate sparse data - mostly zeros with occasional random values
3952
fn generate_sparse_data(size: usize) -> Vec<u32> {
40-
let mut rng = StdRng::seed_from_u64(black_box(SEED));
53+
let mut rng = StdRng::seed_from_u64(SEED);
4154
(0..size)
4255
.map(|_| {
4356
if rng.random_bool(0.9) {
@@ -50,8 +63,8 @@ fn generate_sparse_data(size: usize) -> Vec<u32> {
5063
}
5164

5265
/// Generate constant data - best case for compression
53-
fn generate_constant_data(size: usize, value: u32) -> Vec<u32> {
54-
vec![value; size]
66+
fn generate_constant_data(size: usize) -> Vec<u32> {
67+
vec![SEED as u32; size]
5568
}
5669

5770
/// Generate data with powers of two
@@ -122,18 +135,22 @@ fn decompress_data(codec: &mut FastPFOR, compressed: &[u32], original_size: usiz
122135
fn benchmark_compression(c: &mut Criterion) {
123136
let mut group = c.benchmark_group("compression");
124137

125-
let patterns: Vec<(&str, fn(usize) -> Vec<u32>)> = vec![
126-
("uniform_small", |size| generate_uniform_data(size, 1000)),
127-
("uniform_large", |size| {
128-
generate_uniform_data(size, u32::MAX)
129-
}),
138+
let patterns: &[(&str, DataGeneratorFn)] = &[
139+
(
140+
"uniform_small_value_distribution",
141+
generate_uniform_data_small_value_distribution,
142+
),
143+
(
144+
"uniform_large_value_distribution",
145+
generate_uniform_data_large_value_distribution,
146+
),
130147
("clustered", generate_clustered_data),
131148
("sequential", generate_sequential_data),
132149
("sparse", generate_sparse_data),
133150
];
134151

135152
for &size in SIZES {
136-
for (name, generator) in &patterns {
153+
for (name, generator) in patterns {
137154
let data = generator(size);
138155
group.throughput(Throughput::Elements(size as u64));
139156
group.bench_with_input(BenchmarkId::new(*name, size), &data, |b, data| {
@@ -151,18 +168,22 @@ fn benchmark_compression(c: &mut Criterion) {
151168
fn benchmark_decompression(c: &mut Criterion) {
152169
let mut group = c.benchmark_group("decompression");
153170

154-
let patterns: Vec<(&str, fn(usize) -> Vec<u32>)> = vec![
155-
("uniform_small", |size| generate_uniform_data(size, 1000)),
156-
("uniform_large", |size| {
157-
generate_uniform_data(size, u32::MAX)
158-
}),
171+
let patterns: &[(&str, DataGeneratorFn)] = &[
172+
(
173+
"uniform_small_value_distribution",
174+
generate_uniform_data_small_value_distribution,
175+
),
176+
(
177+
"uniform_large_value_distribution",
178+
generate_uniform_data_large_value_distribution,
179+
),
159180
("clustered", generate_clustered_data),
160181
("sequential", generate_sequential_data),
161182
("sparse", generate_sparse_data),
162183
];
163184

164185
for &size in SIZES {
165-
for (name, generator) in &patterns {
186+
for (name, generator) in patterns {
166187
let data = generator(size);
167188
let compressed = prepare_compressed_data(&data, BLOCK_SIZE_128);
168189

@@ -187,7 +208,7 @@ fn benchmark_roundtrip(c: &mut Criterion) {
187208
let mut group = c.benchmark_group("roundtrip");
188209

189210
for &size in SIZES {
190-
let data = generate_uniform_data(size, 1000);
211+
let data = generate_uniform_data_small_value_distribution(size);
191212

192213
group.throughput(Throughput::Elements(size as u64));
193214
group.bench_with_input(
@@ -239,7 +260,7 @@ fn benchmark_block_sizes(c: &mut Criterion) {
239260
let mut group = c.benchmark_group("block_sizes");
240261

241262
let size = *SIZES.last().unwrap();
242-
let data = generate_uniform_data(size, 1000);
263+
let data = generate_uniform_data_small_value_distribution(size);
243264

244265
let block_sizes = [BLOCK_SIZE_128, BLOCK_SIZE_256];
245266

@@ -275,22 +296,32 @@ fn benchmark_compression_ratio(c: &mut Criterion) {
275296
group.sample_size(20); // Fewer samples since we're measuring ratio, not just speed
276297

277298
let size = *SIZES.last().unwrap();
278-
let patterns = vec![
279-
("uniform_small", generate_uniform_data(size, 100)),
280-
("uniform_medium", generate_uniform_data(size, 10000)),
281-
("uniform_large", generate_uniform_data(size, u32::MAX)),
282-
("clustered", generate_clustered_data(size)),
283-
("sequential", generate_sequential_data(size)),
284-
("sparse", generate_sparse_data(size)),
285-
("constant", generate_constant_data(size, 42)),
286-
("geometric", generate_geometric_data(size)),
299+
let patterns: &[(&str, DataGeneratorFn)] = &[
300+
(
301+
"uniform_small_distribution",
302+
generate_uniform_data_small_value_distribution,
303+
),
304+
(
305+
"uniform_large_distribution",
306+
generate_uniform_data_large_value_distribution,
307+
),
308+
("clustered", generate_clustered_data),
309+
("sequential", generate_sequential_data),
310+
("sparse", generate_sparse_data),
311+
("constant", generate_constant_data),
312+
("geometric", generate_geometric_data),
287313
];
288314

289-
for (name, data) in patterns {
290-
group.bench_function(name, |b| {
315+
for (name, data_fn) in patterns {
316+
let data = data_fn(size);
317+
group.bench_function(*name, |b| {
291318
b.iter(|| {
292319
let mut codec = FastPFOR::default();
293320
let compressed_size = compress_data(&mut codec, black_box(&data));
321+
#[expect(
322+
clippy::cast_precision_loss,
323+
reason = "Loss of precision is acceptable for compression ratio calculation"
324+
)]
294325
let ratio = data.len() as f64 / compressed_size as f64;
295326
black_box(ratio)
296327
});

0 commit comments

Comments
 (0)