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