blob: a3b5f392a3115c0e1e9e24c0a661e3b0de6acc7e [file] [log] [blame]
use std::{
collections::*,
sync::{atomic::*, *},
thread,
};
use arena::MonoIncArena;
use bytes::*;
use criterion::*;
use rand::prelude::*;
use skiplist::*;
// #[cfg(not(target_env = "msvc"))]
// use tikv_jemallocator::Jemalloc;
// #[cfg(not(target_env = "msvc"))]
// #[global_allocator]
// static GLOBAL: Jemalloc = Jemalloc;
fn skiplist_round(
l: &Skiplist<FixedLengthSuffixComparator, MonoIncArena>,
case: &(Bytes, bool),
exp: &Bytes,
) {
if case.1 {
if let Some(v) = l.get(&case.0) {
assert_eq!(v, exp);
}
} else {
l.put(&case.0, exp);
}
}
fn append_ts(key: &mut BytesMut, ts: u64) {
key.put_u64(ts);
}
fn random_key(rng: &mut ThreadRng) -> Bytes {
let mut key = BytesMut::with_capacity(16);
unsafe {
rng.fill_bytes(&mut *(&mut key.chunk_mut()[..8] as *mut _ as *mut [u8]));
key.advance_mut(8);
}
append_ts(&mut key, 0);
key.freeze()
}
fn bench_read_write_skiplist_frac(b: &mut Bencher<'_>, frac: &usize) {
let frac = *frac;
let value = Bytes::from_static(b"00123");
let comp = FixedLengthSuffixComparator::new(8);
let arena = MonoIncArena::new(1 << 10);
let list = Skiplist::with_arena(comp, arena);
let l = list.clone();
let stop = Arc::new(AtomicBool::new(false));
let s = stop.clone();
let v = value.clone();
let handle = thread::spawn(move || {
let mut rng = rand::thread_rng();
while !s.load(Ordering::SeqCst) {
let key = random_key(&mut rng);
let case = (key, frac > rng.gen_range(0..11));
skiplist_round(&l, &case, &v);
}
});
let mut rng = rand::thread_rng();
b.iter_batched_ref(
|| (random_key(&mut rng), frac > rng.gen_range(0..11)),
|case| skiplist_round(&list, case, &value),
BatchSize::SmallInput,
);
stop.store(true, Ordering::SeqCst);
handle.join().unwrap();
}
fn bench_read_write_skiplist(c: &mut Criterion) {
let mut group = c.benchmark_group("skiplist_read_write");
for i in 0..=10 {
group.bench_with_input(
BenchmarkId::from_parameter(i),
&i,
bench_read_write_skiplist_frac,
);
}
group.finish();
}
fn map_round(m: &Mutex<HashMap<Bytes, Bytes>>, case: &(Bytes, bool), exp: &Bytes) {
if case.1 {
let rm = m.lock().unwrap();
let value = rm.get(&case.0);
if let Some(v) = value {
assert_eq!(v, exp);
}
} else {
let mut rm = m.lock().unwrap();
rm.insert(case.0.clone(), exp.clone());
}
}
fn bench_read_write_map_frac(b: &mut Bencher<'_>, frac: &usize) {
let frac = *frac;
let value = Bytes::from_static(b"00123");
let map = Arc::new(Mutex::new(HashMap::with_capacity(512 << 10)));
let map_in_thread = map.clone();
let stop = Arc::new(AtomicBool::new(false));
let thread_stop = stop.clone();
let v = value.clone();
let handle = thread::spawn(move || {
let mut rng = rand::thread_rng();
while !thread_stop.load(Ordering::SeqCst) {
let f = rng.gen_range(0..11);
let case = (random_key(&mut rng), f < frac);
map_round(&map_in_thread, &case, &v);
}
});
let mut rng = rand::thread_rng();
b.iter_batched_ref(
|| {
let f = rng.gen_range(0..11);
(random_key(&mut rng), f < frac)
},
|case| map_round(&map, case, &value),
BatchSize::SmallInput,
);
stop.store(true, Ordering::SeqCst);
handle.join().unwrap();
}
fn bench_read_write_map(c: &mut Criterion) {
let mut group = c.benchmark_group("map_read_write");
for i in 0..=10 {
group.bench_with_input(
BenchmarkId::from_parameter(i),
&i,
bench_read_write_map_frac,
);
}
group.finish();
}
fn bench_write_skiplist(c: &mut Criterion) {
let comp = FixedLengthSuffixComparator::new(8);
let arena = MonoIncArena::new(1 << 10);
let list = Skiplist::with_arena(comp, arena);
let value = Bytes::from_static(b"00123");
let l = list.clone();
let stop = Arc::new(AtomicBool::new(false));
let s = stop.clone();
let v = value.clone();
let handle = thread::spawn(move || {
let mut rng = rand::thread_rng();
while !s.load(Ordering::SeqCst) {
let case = (random_key(&mut rng), false);
skiplist_round(&l, &case, &v);
}
});
let mut rng = rand::thread_rng();
c.bench_function("skiplist_write", |b| {
b.iter_batched(
|| random_key(&mut rng),
|key| {
list.put(&key, &value);
},
BatchSize::SmallInput,
)
});
stop.store(true, Ordering::SeqCst);
handle.join().unwrap();
}
criterion_group!(
benches,
bench_read_write_skiplist,
bench_read_write_map,
bench_write_skiplist
);
criterion_main!(benches);