use anyhow::Result;
use clap::Parser;
use dsi_progress_logger::*;
use rand::rngs::SmallRng;
use rand::{RngExt, SeedableRng};
use std::hint::black_box;
use sux::prelude::*;
use value_traits::slices::*;
#[derive(Parser, Debug)]
#[command(about = "Benchmarks bit-field vectors", long_about = None)]
struct Args {
width: usize,
log2_size: usize,
#[arg(short, long, default_value = "10")]
repeats: usize,
#[arg(short, long, default_value = "10000000")]
n: usize,
}
pub fn main() -> Result<()> {
env_logger::builder()
.filter_level(log::LevelFilter::Info)
.try_init()?;
let args = Args::parse();
let mut a = BitFieldVec::<usize>::new(args.width, 1 << args.log2_size);
let mask = (1 << args.log2_size) - 1;
let mut pl = ProgressLogger::default();
for _ in 0..args.repeats {
let mut rand = SmallRng::seed_from_u64(0);
pl.item_name("write");
pl.start("Writing...");
for _ in 0..args.n {
let x = rand.random::<u64>() as usize & mask;
unsafe { a.set_value_unchecked(x, 1) };
black_box(());
}
pl.done_with_count(args.n);
pl.item_name("read");
pl.start("Reading (random)...");
for _ in 0..args.n {
unsafe {
black_box(a.get_value_unchecked(rand.random::<u64>() as usize & mask));
}
}
pl.done_with_count(args.n);
pl.start("Reading (sequential)...");
for i in 0..args.n {
black_box(unsafe { a.get_value_unchecked(i) });
}
pl.done_with_count(args.n);
let mut iter = a.into_unchecked_iter();
pl.item_name("item");
pl.start("Scanning (unchecked) ...");
for _ in 0..args.n {
black_box(unsafe { iter.next_unchecked() });
}
pl.done_with_count(args.n);
let mut iter = a.into_unchecked_iter_back();
pl.item_name("item");
pl.start("Scanning (backward unchecked) ...");
for _ in 0..args.n {
black_box(unsafe { iter.next_unchecked() });
}
pl.done_with_count(args.n);
}
Ok(())
}