add rand put and get benchmarks

without.crypto
Dan Burkert 10 years ago
parent a37bf556f2
commit c38f094aff
  1. 26
      src/cursor.rs
  2. 45
      src/lib.rs
  3. 117
      src/transaction.rs

@ -228,6 +228,7 @@ mod test {
use ffi::*; use ffi::*;
use super::*; use super::*;
use transaction::*; use transaction::*;
use test_utils::setup_bench_db;
#[test] #[test]
fn test_iter() { fn test_iter() {
@ -371,28 +372,9 @@ mod test {
cursor.get(None, None, MDB_LAST).unwrap()); cursor.get(None, None, MDB_LAST).unwrap());
} }
fn setup_bench_db<'a>(num_rows: u32) -> (io::TempDir, Environment) {
let dir = io::TempDir::new("test").unwrap();
let env = Environment::new().open(dir.path(), io::USER_RWX).unwrap();
{
let db = env.open_db(None).unwrap();
let mut txn = env.begin_write_txn().unwrap();
for i in range(0, num_rows) {
txn.put(db,
format!("key{}", i).as_bytes(),
format!("val{}", i).as_bytes(),
WriteFlags::empty())
.unwrap();
}
txn.commit().unwrap();
}
(dir, env)
}
/// Benchmark of iterator sequential read performance. /// Benchmark of iterator sequential read performance.
#[bench] #[bench]
fn bench_seq_iter(b: &mut Bencher) { fn bench_get_seq_iter(b: &mut Bencher) {
let n = 100; let n = 100;
let (_dir, env) = setup_bench_db(n); let (_dir, env) = setup_bench_db(n);
let db = env.open_db(None).unwrap(); let db = env.open_db(None).unwrap();
@ -415,7 +397,7 @@ mod test {
/// Benchmark of cursor sequential read performance. /// Benchmark of cursor sequential read performance.
#[bench] #[bench]
fn bench_seq_cursor(b: &mut Bencher) { fn bench_get_seq_cursor(b: &mut Bencher) {
let n = 100; let n = 100;
let (_dir, env) = setup_bench_db(n); let (_dir, env) = setup_bench_db(n);
let db = env.open_db(None).unwrap(); let db = env.open_db(None).unwrap();
@ -438,7 +420,7 @@ mod test {
/// Benchmark of raw LMDB sequential read performance (control). /// Benchmark of raw LMDB sequential read performance (control).
#[bench] #[bench]
fn bench_seq_raw(b: &mut Bencher) { fn bench_get_seq_raw(b: &mut Bencher) {
let n = 100; let n = 100;
let (_dir, env) = setup_bench_db(n); let (_dir, env) = setup_bench_db(n);
let db = env.open_db(None).unwrap(); let db = env.open_db(None).unwrap();

@ -17,7 +17,15 @@ pub use cursor::Cursor;
pub use database::Database; pub use database::Database;
pub use environment::{Environment, EnvironmentBuilder}; pub use environment::{Environment, EnvironmentBuilder};
pub use error::{LmdbResult, LmdbError}; pub use error::{LmdbResult, LmdbError};
pub use transaction::{ReadTransaction, WriteTransaction, RoTransaction, RwTransaction}; pub use transaction::{
ReadTransaction,
RoTransaction,
RwTransaction,
Transaction,
TransactionExt,
WriteTransaction,
};
pub use ffi::{DatabaseFlags, EnvironmentFlags, WriteFlags};
macro_rules! lmdb_try { macro_rules! lmdb_try {
($expr:expr) => ({ ($expr:expr) => ({
@ -45,3 +53,38 @@ mod database;
mod environment; mod environment;
mod error; mod error;
mod transaction; mod transaction;
#[cfg(test)]
mod test_utils {
use std::io;
use super::*;
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) -> (io::TempDir, Environment) {
let dir = io::TempDir::new("test").unwrap();
let env = Environment::new().open(dir.path(), io::USER_RWX).unwrap();
{
let db = env.open_db(None).unwrap();
let mut txn = env.begin_write_txn().unwrap();
for i in range(0, num_rows) {
txn.put(db,
get_key(i).as_bytes(),
get_data(i).as_bytes(),
WriteFlags::empty())
.unwrap();
}
txn.commit().unwrap();
}
(dir, env)
}
}

@ -71,7 +71,6 @@ pub trait ReadTransaction<'env> : Transaction<'env> {
len: data_val.mv_size as uint len: data_val.mv_size as uint
}); });
Ok(Some(slice)) Ok(Some(slice))
} else if err_code == ffi::MDB_NOTFOUND { } else if err_code == ffi::MDB_NOTFOUND {
Ok(None) Ok(None)
} else { } else {
@ -91,7 +90,6 @@ pub trait ReadTransaction<'env> : Transaction<'env> {
unsafe { unsafe {
try!(lmdb_result(ffi::mdb_dbi_flags(self.txn(), db.dbi(), &mut flags))); try!(lmdb_result(ffi::mdb_dbi_flags(self.txn(), db.dbi(), &mut flags)));
} }
Ok(DatabaseFlags::from_bits_truncate(flags)) Ok(DatabaseFlags::from_bits_truncate(flags))
} }
} }
@ -153,7 +151,6 @@ pub trait WriteTransaction<'env> : ReadTransaction<'env> {
data: data_val.mv_data as *const u8, data: data_val.mv_data as *const u8,
len: data_val.mv_size as uint len: data_val.mv_size as uint
}); });
Ok(BufWriter::new(slice)) Ok(BufWriter::new(slice))
} }
} }
@ -282,13 +279,17 @@ impl <'env> WriteTransaction<'env> for RwTransaction<'env> { }
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use libc::{c_uint, c_void, size_t};
use std::io; use std::io;
use std::ptr;
use std::rand::{Rng, XorShiftRng};
use std::sync::{Arc, Barrier, Future}; use std::sync::{Arc, Barrier, Future};
use test::{Bencher, black_box};
use environment::*; use environment::*;
use ffi::*; use ffi::*;
use super::*; use super::*;
use test_utils::*;
#[test] #[test]
fn test_put_get_del() { fn test_put_get_del() {
@ -442,4 +443,112 @@ mod test {
txn.get(db, format!("{}{}", key, i).as_bytes()).unwrap().unwrap()); txn.get(db, format!("{}{}", key, i).as_bytes()).unwrap().unwrap());
} }
} }
#[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_read_txn().unwrap();
let mut keys: Vec<String> = range(0, n).map(|n| get_key(n))
.collect::<Vec<_>>();
XorShiftRng::new_unseeded().shuffle(keys.as_mut_slice());
b.iter(|| {
let mut i = 0u;
for key in keys.iter() {
i = i + txn.get(db, key.as_bytes()).unwrap().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_read_txn().unwrap();
let mut keys: Vec<String> = range(0, n).map(|n| get_key(n))
.collect::<Vec<_>>();
XorShiftRng::new_unseeded().shuffle(keys.as_mut_slice());
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 = 0u64;
for key in keys.iter() {
key_val.mv_size = key.len() as u64;
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)> = range(0, n).map(|n| (get_key(n), get_data(n)))
.collect::<Vec<_>>();
XorShiftRng::new_unseeded().shuffle(items.as_mut_slice());
b.iter(|| {
// TODO: change this to just a transaction renew, instead of a new transaction
let mut txn = env.begin_write_txn().unwrap();
let mut i = 0u;
for &(ref key, ref data) in items.iter() {
txn.put(db, key.as_bytes(), data.as_bytes(), 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)> = range(0, n).map(|n| (get_key(n), get_data(n)))
.collect::<Vec<_>>();
XorShiftRng::new_unseeded().shuffle(items.as_mut_slice());
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 {
// TODO: change this to just a transaction renew, instead of a new transaction
let mut txn: *mut MDB_txn = ptr::null_mut();
mdb_txn_begin(env, ptr::null_mut(), 0, &mut txn);
let mut i = 0i32;
for &(ref key, ref data) in items.iter() {
key_val.mv_size = key.len() as u64;
key_val.mv_data = key.as_bytes().as_ptr() as *mut _;
data_val.mv_size = data.len() as u64;
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);
});
}
} }

Loading…
Cancel
Save