parent
04e544977f
commit
5849f37f31
@ -0,0 +1,106 @@ |
||||
#![feature(test)] |
||||
|
||||
extern crate lmdb; |
||||
extern crate lmdb_rkv_sys as ffi; |
||||
extern crate test; |
||||
|
||||
mod utils; |
||||
|
||||
use ffi::*; |
||||
use lmdb::{Cursor, Result, RoCursor, Transaction}; |
||||
use std::ptr; |
||||
use test::{Bencher, black_box}; |
||||
use utils::*; |
||||
|
||||
/// Benchmark of iterator sequential read performance.
|
||||
#[bench] |
||||
fn bench_get_seq_iter(b: &mut Bencher) { |
||||
let n = 100; |
||||
let (_dir, env) = setup_bench_db(n); |
||||
let db = env.open_db(None).unwrap(); |
||||
let txn = env.begin_ro_txn().unwrap(); |
||||
|
||||
b.iter(|| { |
||||
let mut cursor = txn.open_ro_cursor(db).unwrap(); |
||||
let mut i = 0; |
||||
let mut count = 0u32; |
||||
|
||||
for (key, data) in cursor.iter().map(Result::unwrap) { |
||||
i = i + key.len() + data.len(); |
||||
count = count + 1; |
||||
} |
||||
for (key, data) in cursor.iter().filter_map(Result::ok) { |
||||
i = i + key.len() + data.len(); |
||||
count = count + 1; |
||||
} |
||||
|
||||
fn iterate<'a>(cursor: &mut RoCursor) -> Result<()> { |
||||
let mut i = 0; |
||||
let mut count = 0u32; |
||||
for result in cursor.iter() { |
||||
let (key, data) = result?; |
||||
i = i + key.len() + data.len(); |
||||
count = count + 1; |
||||
} |
||||
Ok(()) |
||||
} |
||||
iterate(&mut cursor).unwrap(); |
||||
|
||||
black_box(i); |
||||
assert_eq!(count, n); |
||||
}); |
||||
} |
||||
|
||||
/// Benchmark of cursor sequential read performance.
|
||||
#[bench] |
||||
fn bench_get_seq_cursor(b: &mut Bencher) { |
||||
let n = 100; |
||||
let (_dir, env) = setup_bench_db(n); |
||||
let db = env.open_db(None).unwrap(); |
||||
let txn = env.begin_ro_txn().unwrap(); |
||||
|
||||
b.iter(|| { |
||||
let cursor = txn.open_ro_cursor(db).unwrap(); |
||||
let mut i = 0; |
||||
let mut count = 0u32; |
||||
|
||||
while let Ok((key_opt, val)) = cursor.get(None, None, MDB_NEXT) { |
||||
i += key_opt.map(|key| key.len()).unwrap_or(0) + val.len(); |
||||
count += 1; |
||||
} |
||||
|
||||
black_box(i); |
||||
assert_eq!(count, n); |
||||
}); |
||||
} |
||||
|
||||
/// Benchmark of raw LMDB sequential read performance (control).
|
||||
#[bench] |
||||
fn bench_get_seq_raw(b: &mut Bencher) { |
||||
let n = 100; |
||||
let (_dir, env) = setup_bench_db(n); |
||||
let db = env.open_db(None).unwrap(); |
||||
|
||||
let dbi: MDB_dbi = db.dbi(); |
||||
let _txn = env.begin_ro_txn().unwrap(); |
||||
let txn = _txn.txn(); |
||||
|
||||
let mut key = MDB_val { mv_size: 0, mv_data: ptr::null_mut() }; |
||||
let mut data = MDB_val { mv_size: 0, mv_data: ptr::null_mut() }; |
||||
let mut cursor: *mut MDB_cursor = ptr::null_mut(); |
||||
|
||||
b.iter(|| unsafe { |
||||
mdb_cursor_open(txn, dbi, &mut cursor); |
||||
let mut i = 0; |
||||
let mut count = 0u32; |
||||
|
||||
while mdb_cursor_get(cursor, &mut key, &mut data, MDB_NEXT) == 0 { |
||||
i += key.mv_size + data.mv_size; |
||||
count += 1; |
||||
}; |
||||
|
||||
black_box(i); |
||||
assert_eq!(count, n); |
||||
mdb_cursor_close(cursor); |
||||
}); |
||||
} |
@ -0,0 +1,118 @@ |
||||
#![feature(test)] |
||||
|
||||
extern crate libc; |
||||
extern crate lmdb; |
||||
extern crate lmdb_rkv_sys as ffi; |
||||
extern crate rand; |
||||
extern crate test; |
||||
|
||||
mod utils; |
||||
|
||||
use ffi::*; |
||||
use libc::size_t; |
||||
use lmdb::{Transaction, WriteFlags}; |
||||
use rand::{Rng, XorShiftRng}; |
||||
use std::ptr; |
||||
use test::{Bencher, black_box}; |
||||
use utils::*; |
||||
|
||||
#[bench] |
||||
fn bench_get_rand(b: &mut Bencher) { |
||||
let n = 100u32; |
||||
let (_dir, env) = setup_bench_db(n); |
||||
let db = env.open_db(None).unwrap(); |
||||
let txn = env.begin_ro_txn().unwrap(); |
||||
|
||||
let mut keys: Vec<String> = (0..n).map(|n| get_key(n)).collect(); |
||||
XorShiftRng::new_unseeded().shuffle(&mut keys[..]); |
||||
|
||||
b.iter(|| { |
||||
let mut i = 0usize; |
||||
for key in &keys { |
||||
i = i + txn.get(db, key).unwrap().len(); |
||||
} |
||||
black_box(i); |
||||
}); |
||||
} |
||||
|
||||
#[bench] |
||||
fn bench_get_rand_raw(b: &mut Bencher) { |
||||
let n = 100u32; |
||||
let (_dir, env) = setup_bench_db(n); |
||||
let db = env.open_db(None).unwrap(); |
||||
let _txn = env.begin_ro_txn().unwrap(); |
||||
|
||||
let mut keys: Vec<String> = (0..n).map(|n| get_key(n)).collect(); |
||||
XorShiftRng::new_unseeded().shuffle(&mut keys[..]); |
||||
|
||||
let dbi = db.dbi(); |
||||
let txn = _txn.txn(); |
||||
|
||||
let mut key_val: MDB_val = MDB_val { mv_size: 0, mv_data: ptr::null_mut() }; |
||||
let mut data_val: MDB_val = MDB_val { mv_size: 0, mv_data: ptr::null_mut() }; |
||||
|
||||
b.iter(|| unsafe { |
||||
let mut i: size_t = 0; |
||||
for key in &keys { |
||||
key_val.mv_size = key.len() as size_t; |
||||
key_val.mv_data = key.as_bytes().as_ptr() as *mut _; |
||||
|
||||
mdb_get(txn, dbi, &mut key_val, &mut data_val); |
||||
|
||||
i = i + key_val.mv_size; |
||||
} |
||||
black_box(i); |
||||
}); |
||||
} |
||||
|
||||
#[bench] |
||||
fn bench_put_rand(b: &mut Bencher) { |
||||
let n = 100u32; |
||||
let (_dir, env) = setup_bench_db(0); |
||||
let db = env.open_db(None).unwrap(); |
||||
|
||||
let mut items: Vec<(String, String)> = (0..n).map(|n| (get_key(n), get_data(n))).collect(); |
||||
XorShiftRng::new_unseeded().shuffle(&mut items[..]); |
||||
|
||||
b.iter(|| { |
||||
let mut txn = env.begin_rw_txn().unwrap(); |
||||
for &(ref key, ref data) in items.iter() { |
||||
txn.put(db, key, data, WriteFlags::empty()).unwrap(); |
||||
} |
||||
txn.abort(); |
||||
}); |
||||
} |
||||
|
||||
#[bench] |
||||
fn bench_put_rand_raw(b: &mut Bencher) { |
||||
let n = 100u32; |
||||
let (_dir, _env) = setup_bench_db(0); |
||||
let db = _env.open_db(None).unwrap(); |
||||
|
||||
let mut items: Vec<(String, String)> = (0..n).map(|n| (get_key(n), get_data(n))).collect(); |
||||
XorShiftRng::new_unseeded().shuffle(&mut items[..]); |
||||
|
||||
let dbi = db.dbi(); |
||||
let env = _env.env(); |
||||
|
||||
let mut key_val: MDB_val = MDB_val { mv_size: 0, mv_data: ptr::null_mut() }; |
||||
let mut data_val: MDB_val = MDB_val { mv_size: 0, mv_data: ptr::null_mut() }; |
||||
|
||||
b.iter(|| unsafe { |
||||
let mut txn: *mut MDB_txn = ptr::null_mut(); |
||||
mdb_txn_begin(env, ptr::null_mut(), 0, &mut txn); |
||||
|
||||
let mut i: ::libc::c_int = 0; |
||||
for &(ref key, ref data) in items.iter() { |
||||
|
||||
key_val.mv_size = key.len() as size_t; |
||||
key_val.mv_data = key.as_bytes().as_ptr() as *mut _; |
||||
data_val.mv_size = data.len() as size_t; |
||||
data_val.mv_data = data.as_bytes().as_ptr() as *mut _; |
||||
|
||||
i += mdb_put(txn, dbi, &mut key_val, &mut data_val, 0); |
||||
} |
||||
assert_eq!(0, i); |
||||
mdb_txn_abort(txn); |
||||
}); |
||||
} |
@ -0,0 +1,28 @@ |
||||
extern crate lmdb; |
||||
extern crate tempdir; |
||||
|
||||
use lmdb::{Environment, Transaction, WriteFlags}; |
||||
use self::tempdir::TempDir; |
||||
|
||||
pub fn get_key(n: u32) -> String { |
||||
format!("key{}", n) |
||||
} |
||||
|
||||
pub fn get_data(n: u32) -> String { |
||||
format!("data{}", n) |
||||
} |
||||
|
||||
pub fn setup_bench_db<'a>(num_rows: u32) -> (TempDir, Environment) { |
||||
let dir = TempDir::new("test").unwrap(); |
||||
let env = Environment::new().open(dir.path()).unwrap(); |
||||
|
||||
{ |
||||
let db = env.open_db(None).unwrap(); |
||||
let mut txn = env.begin_rw_txn().unwrap(); |
||||
for i in 0..num_rows { |
||||
txn.put(db, &get_key(i), &get_data(i), WriteFlags::empty()).unwrap(); |
||||
} |
||||
txn.commit().unwrap(); |
||||
} |
||||
(dir, env) |
||||
} |
Loading…
Reference in new issue