separate benches from tests

without.crypto
Myk Melez 6 years ago
parent 04e544977f
commit 5849f37f31
  1. 106
      benches/cursor.rs
  2. 118
      benches/transaction.rs
  3. 28
      benches/utils.rs
  4. 98
      src/cursor.rs
  5. 26
      src/lib.rs
  6. 107
      src/transaction.rs

@ -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)
}

@ -350,17 +350,12 @@ impl <'txn> Iterator for IterDup<'txn> {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use std::ptr;
use test::{Bencher, black_box};
use tempdir::TempDir; use tempdir::TempDir;
use environment::*; use environment::*;
use ffi::*; use ffi::*;
use flags::*; use flags::*;
use super::*; use super::*;
use test_utils::*;
#[test] #[test]
fn test_get() { fn test_get() {
@ -613,97 +608,4 @@ mod test {
assert_eq!((Some(&b"key2"[..]), &b"val2"[..]), assert_eq!((Some(&b"key2"[..]), &b"val2"[..]),
cursor.get(None, None, MDB_LAST).unwrap()); cursor.get(None, None, MDB_LAST).unwrap());
} }
/// 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);
});
}
} }

@ -1,7 +1,6 @@
//! Idiomatic and safe APIs for interacting with the //! Idiomatic and safe APIs for interacting with the
//! [Lightning Memory-mapped Database (LMDB)](https://symas.com/lmdb). //! [Lightning Memory-mapped Database (LMDB)](https://symas.com/lmdb).
#![cfg_attr(test, feature(test))]
#![deny(missing_docs)] #![deny(missing_docs)]
#![doc(html_root_url = "https://docs.rs/lmdb-rkv/0.11.4")] #![doc(html_root_url = "https://docs.rs/lmdb-rkv/0.11.4")]
@ -9,9 +8,7 @@ extern crate libc;
extern crate lmdb_rkv_sys as ffi; extern crate lmdb_rkv_sys as ffi;
extern crate byteorder; extern crate byteorder;
#[cfg(test)] extern crate rand;
#[cfg(test)] extern crate tempdir; #[cfg(test)] extern crate tempdir;
#[cfg(test)] extern crate test;
#[macro_use] extern crate bitflags; #[macro_use] extern crate bitflags;
pub use cursor::{ pub use cursor::{
@ -73,29 +70,6 @@ mod test_utils {
use super::*; 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) -> (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)
}
/// Regression test for https://github.com/danburkert/lmdb-rs/issues/21. /// Regression test for https://github.com/danburkert/lmdb-rs/issues/21.
/// This test reliably segfaults when run against lmbdb compiled with opt level -O3 and newer /// This test reliably segfaults when run against lmbdb compiled with opt level -O3 and newer
/// GCC compilers. /// GCC compilers.

@ -395,22 +395,16 @@ impl <'env> Transaction for RwTransaction<'env> {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use libc::size_t;
use rand::{Rng, XorShiftRng};
use std::io::Write; use std::io::Write;
use std::ptr;
use std::sync::{Arc, Barrier}; use std::sync::{Arc, Barrier};
use std::thread::{self, JoinHandle}; use std::thread::{self, JoinHandle};
use test::{Bencher, black_box};
use tempdir::TempDir; use tempdir::TempDir;
use environment::*; use environment::*;
use error::*; use error::*;
use ffi::*;
use flags::*; use flags::*;
use super::*; use super::*;
use test_utils::*;
use cursor::Cursor; use cursor::Cursor;
#[test] #[test]
@ -752,105 +746,4 @@ mod test {
assert_eq!(stat.entries(), 8); assert_eq!(stat.entries(), 8);
} }
} }
#[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);
});
}
} }

Loading…
Cancel
Save