#![allow(clippy::result_large_err)]
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Throughput};
use numrs2::io::{
deserialize_from_file, load_all_npz_arrays, save_npz_arrays, serialize_to_file, SerializeFormat,
};
use numrs2::prelude::*;
use std::collections::HashMap;
use std::hint::black_box;
use std::io::Cursor;
fn bench_npy_write(c: &mut Criterion) {
let mut group = c.benchmark_group("npy_write");
for n in [1_000usize, 10_000, 100_000, 1_000_000].iter() {
group.throughput(Throughput::Bytes((*n * 8) as u64));
let array = Array::from_vec(vec![0.0f64; *n]);
group.bench_with_input(BenchmarkId::new("f64_1d", n), n, |b, _| {
b.iter(|| {
let mut cursor = Cursor::new(Vec::new());
if let Ok(()) = serialize_to_file(&array, &mut cursor, SerializeFormat::Npy) {
black_box(cursor.into_inner());
}
});
});
}
group.finish();
}
fn bench_npy_read(c: &mut Criterion) {
let mut group = c.benchmark_group("npy_read");
for n in [1_000usize, 10_000, 100_000, 1_000_000].iter() {
group.throughput(Throughput::Bytes((*n * 8) as u64));
let array = Array::from_vec(vec![0.0f64; *n]);
let mut write_cursor = Cursor::new(Vec::new());
if let Ok(()) = serialize_to_file(&array, &mut write_cursor, SerializeFormat::Npy) {
let buffer = write_cursor.into_inner();
group.bench_with_input(BenchmarkId::new("f64_1d", n), n, |b, _| {
b.iter(|| {
let cursor = Cursor::new(buffer.as_slice());
if let Ok(arr) = deserialize_from_file::<f64, _>(cursor, SerializeFormat::Npy) {
black_box(arr);
}
});
});
}
}
group.finish();
}
fn bench_npz_write_uncompressed(c: &mut Criterion) {
let mut group = c.benchmark_group("npz_write_uncompressed");
for total in [10_000usize, 100_000, 1_000_000].iter() {
group.throughput(Throughput::Bytes((*total * 8) as u64));
let per_array = total / 3;
let mut arrays: HashMap<String, Array<f64>> = HashMap::new();
arrays.insert(
"arr_a".to_string(),
Array::from_vec(vec![0.0f64; per_array]),
);
arrays.insert(
"arr_b".to_string(),
Array::from_vec(vec![1.0f64; per_array]),
);
arrays.insert(
"arr_c".to_string(),
Array::from_vec(vec![2.0f64; per_array]),
);
group.bench_with_input(BenchmarkId::new("3_arrays", total), total, |b, _| {
b.iter(|| {
let cursor = Cursor::new(Vec::new());
if let Ok(()) = save_npz_arrays(&arrays, cursor, false) {
black_box(());
}
});
});
}
group.finish();
}
fn bench_npz_write_compressed(c: &mut Criterion) {
let mut group = c.benchmark_group("npz_write_compressed");
for total in [10_000usize, 100_000, 1_000_000].iter() {
group.throughput(Throughput::Bytes((*total * 8) as u64));
let per_array = total / 3;
let mut arrays: HashMap<String, Array<f64>> = HashMap::new();
arrays.insert(
"arr_a".to_string(),
Array::from_vec(vec![0.0f64; per_array]),
);
arrays.insert(
"arr_b".to_string(),
Array::from_vec(vec![1.0f64; per_array]),
);
arrays.insert(
"arr_c".to_string(),
Array::from_vec(vec![2.0f64; per_array]),
);
group.bench_with_input(BenchmarkId::new("3_arrays", total), total, |b, _| {
b.iter(|| {
let cursor = Cursor::new(Vec::new());
if let Ok(()) = save_npz_arrays(&arrays, cursor, true) {
black_box(());
}
});
});
}
group.finish();
}
fn bench_npz_read(c: &mut Criterion) {
let mut group = c.benchmark_group("npz_read");
for total in [10_000usize, 100_000].iter() {
group.throughput(Throughput::Bytes((*total * 8) as u64));
let per_array = total / 3;
let mut arrays: HashMap<String, Array<f64>> = HashMap::new();
arrays.insert(
"arr_a".to_string(),
Array::from_vec(vec![0.0f64; per_array]),
);
arrays.insert(
"arr_b".to_string(),
Array::from_vec(vec![1.0f64; per_array]),
);
arrays.insert(
"arr_c".to_string(),
Array::from_vec(vec![2.0f64; per_array]),
);
let mut npz_buf: Vec<u8> = Vec::new();
if let Ok(()) = save_npz_arrays(&arrays, Cursor::new(&mut npz_buf), false) {
group.bench_with_input(BenchmarkId::new("3_arrays", total), total, |b, _| {
b.iter(|| {
let cursor = Cursor::new(npz_buf.as_slice());
if let Ok(result) = load_all_npz_arrays::<f64, _>(cursor) {
black_box(result);
}
});
});
}
}
group.finish();
}
fn bench_npy_roundtrip(c: &mut Criterion) {
let mut group = c.benchmark_group("npy_roundtrip");
let n: usize = 100_000;
group.throughput(Throughput::Bytes((n * 8) as u64));
let array = Array::from_vec(vec![0.0f64; n]);
group.bench_function("f64_100k", |b| {
b.iter(|| {
let mut cursor = Cursor::new(Vec::new());
if let Ok(()) = serialize_to_file(&array, &mut cursor, SerializeFormat::Npy) {
let buffer = cursor.into_inner();
let read_cursor = Cursor::new(buffer.as_slice());
if let Ok(arr) = deserialize_from_file::<f64, _>(read_cursor, SerializeFormat::Npy)
{
black_box(arr);
}
}
});
});
group.finish();
}
criterion_group!(
io_benches,
bench_npy_write,
bench_npy_read,
bench_npz_write_uncompressed,
bench_npz_write_compressed,
bench_npz_read,
bench_npy_roundtrip,
);
criterion_main!(io_benches);