#![feature(test)]
extern crate wt_slice;
extern crate rand;
extern crate test;
use rand::distributions::{Distribution, Uniform};
use wt_slice::*;
use test::Bencher;
enum Cache {
L1,
L2,
L3,
}
enum Config {
Unique,
Dups,
}
impl Cache {
pub fn size(&self) -> usize {
match *self {
Cache::L1 => 1000, Cache::L2 => 10_000, Cache::L3 => 1_000_000, }
}
}
macro_rules! for_each_config {
() => (
#[bench]
fn unique(b: &mut Bencher) {
run(b, Config::Unique);
}
#[bench]
fn dups(b: &mut Bencher) {
run(b, Config::Dups);
}
)
}
macro_rules! for_each_cache {
() => (
mod l1 {
use super::*;
fn run(b: &mut Bencher, config: Config) {
super::run(b, Cache::L1, config)
}
for_each_config!();
}
mod l2 {
use super::*;
fn run(b: &mut Bencher, config: Config) {
super::run(b, Cache::L2, config)
}
for_each_config!();
}
mod l3 {
use super::*;
fn run(b: &mut Bencher, config: Config) {
super::run(b, Cache::L3, config)
}
for_each_config!();
}
)
}
fn generate_inputs(cache: Cache, config: Config) -> (Vec<usize>, Vec<usize>) {
let size = cache.size();
let between = Uniform::from(0..size * 16);
let mut rng = rand::thread_rng();
let mut sample = || {
let x = between.sample(&mut rng);
match config {
Config::Dups => x / 16 * 16,
Config::Unique => x,
}
};
let mut values = (0..size).map(|_| sample()).collect::<Vec<_>>();
values.sort();
let mut lookups = Vec::with_capacity(size);
for _ in 0..size {
lookups.push(sample());
}
(values, lookups)
}
mod lower_bound {
use super::*;
fn run(b: &mut Bencher, cache: Cache, config: Config) {
let (values, lookups) = generate_inputs(cache, config);
let mut iter = lookups.iter().cycle();
b.iter(|| {
values.lower_bound(iter.next().unwrap())
})
}
for_each_cache!();
}
mod upper_bound {
use super::*;
fn run(b: &mut Bencher, cache: Cache, config: Config) {
let (values, lookups) = generate_inputs(cache, config);
let mut iter = lookups.iter().cycle();
b.iter(|| {
values.upper_bound(iter.next().unwrap())
})
}
for_each_cache!();
}
mod equal_range {
use super::*;
fn run(b: &mut Bencher, cache: Cache, config: Config) {
let (values, lookups) = generate_inputs(cache, config);
let mut iter = lookups.iter().cycle();
b.iter(|| {
values.equal_range(iter.next().unwrap())
})
}
for_each_cache!();
}