Merge branch 'hashx-bench' into 'main'
hashx_cachegrind: factor out some common stuff in benchmarks See merge request tpo/core/arti!1529
This commit is contained in:
commit
7d6f5531ce
|
@ -11,68 +11,93 @@
|
|||
|
||||
use iai::black_box;
|
||||
|
||||
fn generate_interp_1000x() {
|
||||
let mut builder = hashx::HashXBuilder::new();
|
||||
builder.runtime(hashx::RuntimeOption::InterpretOnly);
|
||||
for s in 0_u32..1000_u32 {
|
||||
let _ = black_box(builder.build(black_box(&s.to_be_bytes())));
|
||||
/// Bind Rust `HashBuilder` whose `RuntimeOption` is `$runtime_option` to `$builder`
|
||||
//
|
||||
// This and mk_c_equix are macros rather than a function because it avoids us
|
||||
// having to import RuntimeOption::*, etc. or clutter the calls with a local alias.
|
||||
macro_rules! mk_rust { { $builder:ident = $runtime_option:ident } => {
|
||||
let mut $builder = hashx::HashXBuilder::new();
|
||||
$builder.runtime(hashx::RuntimeOption::$runtime_option);
|
||||
} }
|
||||
|
||||
/// Bind a C `HashX` whose `HashXType` is `$hashx_type` to `$ctx`
|
||||
macro_rules! mk_c_equix { { $ctx:ident = $hashx_type:ident } => {
|
||||
let mut $ctx = tor_c_equix::HashX::new(tor_c_equix::HashXType::$hashx_type);
|
||||
} }
|
||||
|
||||
/// Evaluate `$eval` binding `$loopvar` to `0..$max`
|
||||
///
|
||||
/// Applies `black_box` to inputs and outputs.
|
||||
///
|
||||
/// If `$loopvar_map` is supplied, it is a function applied to $loopvar
|
||||
/// to convert from the integer loop variable, to whatever more useful type is needed.
|
||||
//
|
||||
// We expect $loopvar_map:ident even though a closure would be suitable, mostly because
|
||||
// we expect the actual benchmark cases to want to use a short alias like `u32be`
|
||||
macro_rules! bench_loop { {
|
||||
$loopvar:ident, $max:expr $(, $loopvar_map:ident )? => $eval:expr
|
||||
} => {
|
||||
for $loopvar in 0..$max {
|
||||
$(
|
||||
let $loopvar = $loopvar_map($loopvar);
|
||||
)?
|
||||
let $loopvar = black_box($loopvar);
|
||||
let _ = black_box($eval);
|
||||
}
|
||||
} }
|
||||
|
||||
/// Convenience alias to reduce clutter in actual benchmarks
|
||||
const C_HASHX_OK: tor_c_equix::ffi::hashx_result = tor_c_equix::HashXResult::HASHX_OK;
|
||||
|
||||
/// Helper, alias for `u32::to_be_bytes`
|
||||
//
|
||||
// Unfortunately, we can't just `use u32::to_be_bytes`.
|
||||
fn u32be(s: u32) -> [u8; 4] {
|
||||
s.to_be_bytes()
|
||||
}
|
||||
|
||||
fn generate_interp_1000x() {
|
||||
mk_rust!(builder = InterpretOnly);
|
||||
bench_loop! { s, 1000_u32, u32be => builder.build(&s) }
|
||||
}
|
||||
|
||||
fn generate_interp_1000x_c() {
|
||||
let mut ctx = tor_c_equix::HashX::new(tor_c_equix::HashXType::HASHX_TYPE_INTERPRETED);
|
||||
for s in 0_u32..1000_u32 {
|
||||
let _ = black_box(ctx.make(black_box(&s.to_be_bytes())));
|
||||
}
|
||||
mk_c_equix!(ctx = HASHX_TYPE_INTERPRETED);
|
||||
bench_loop! { s, 1000_u32, u32be => ctx.make(&s) }
|
||||
}
|
||||
|
||||
fn generate_compiled_1000x() {
|
||||
let mut builder = hashx::HashXBuilder::new();
|
||||
builder.runtime(hashx::RuntimeOption::CompileOnly);
|
||||
for s in 0_u32..1000_u32 {
|
||||
let _ = black_box(builder.build(black_box(&s.to_be_bytes())));
|
||||
}
|
||||
mk_rust!(builder = CompileOnly);
|
||||
bench_loop! { s, 1000_u32, u32be => builder.build(&s) }
|
||||
}
|
||||
|
||||
fn generate_compiled_1000x_c() {
|
||||
let mut ctx = tor_c_equix::HashX::new(tor_c_equix::HashXType::HASHX_TYPE_COMPILED);
|
||||
for s in 0_u32..1000_u32 {
|
||||
let _ = black_box(ctx.make(black_box(&s.to_be_bytes())));
|
||||
}
|
||||
mk_c_equix!(ctx = HASHX_TYPE_COMPILED);
|
||||
bench_loop! { s, 1000_u32, u32be => ctx.make(&s) }
|
||||
}
|
||||
|
||||
fn interp_u64_hash_1000x() {
|
||||
let mut builder = hashx::HashXBuilder::new();
|
||||
builder.runtime(hashx::RuntimeOption::InterpretOnly);
|
||||
mk_rust!(builder = InterpretOnly);
|
||||
let hashx = builder.build(b"abc").unwrap();
|
||||
for i in 0_u64..1000_u64 {
|
||||
let _ = black_box(hashx.hash_to_u64(black_box(i)));
|
||||
}
|
||||
bench_loop! { i, 1000_u64 => hashx.hash_to_u64(i) }
|
||||
}
|
||||
|
||||
fn interp_8b_hash_1000x_c() {
|
||||
let mut ctx = tor_c_equix::HashX::new(tor_c_equix::HashXType::HASHX_TYPE_INTERPRETED);
|
||||
assert_eq!(ctx.make(b"abc"), tor_c_equix::HashXResult::HASHX_OK);
|
||||
for i in 0_u64..1000_u64 {
|
||||
let _ = black_box(ctx.exec(black_box(i)));
|
||||
}
|
||||
mk_c_equix!(ctx = HASHX_TYPE_INTERPRETED);
|
||||
assert_eq!(ctx.make(b"abc"), C_HASHX_OK);
|
||||
bench_loop! { i, 1000_u64 => ctx.exec(i) }
|
||||
}
|
||||
|
||||
fn compiled_u64_hash_100000x() {
|
||||
let mut builder = hashx::HashXBuilder::new();
|
||||
builder.runtime(hashx::RuntimeOption::CompileOnly);
|
||||
mk_rust!(builder = CompileOnly);
|
||||
let hashx = builder.build(b"abc").unwrap();
|
||||
for i in 0_u64..100000_u64 {
|
||||
let _ = black_box(hashx.hash_to_u64(black_box(i)));
|
||||
}
|
||||
bench_loop! { i, 100000_u64 => hashx.hash_to_u64(i) }
|
||||
}
|
||||
|
||||
fn compiled_8b_hash_100000x_c() {
|
||||
let mut ctx = tor_c_equix::HashX::new(tor_c_equix::HashXType::HASHX_TYPE_COMPILED);
|
||||
assert_eq!(ctx.make(b"abc"), tor_c_equix::HashXResult::HASHX_OK);
|
||||
for i in 0_u64..100000_u64 {
|
||||
let _ = black_box(ctx.exec(black_box(i)));
|
||||
}
|
||||
mk_c_equix!(ctx = HASHX_TYPE_COMPILED);
|
||||
assert_eq!(ctx.make(b"abc"), C_HASHX_OK);
|
||||
bench_loop! { i, 100000_u64 => ctx.exec(i) }
|
||||
}
|
||||
|
||||
iai::main!(
|
||||
|
|
Loading…
Reference in New Issue