diff --git a/.gitignore b/.gitignore index 346ef9afae..6b8d4ab214 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ Cargo.lock *.pk *.sk *.raw_keypairs +flamegraph.svg +perf.data* diff --git a/eth2/utils/cached_tree_hash/Cargo.toml b/eth2/utils/cached_tree_hash/Cargo.toml index c8881eb0fd..c33f20add9 100644 --- a/eth2/utils/cached_tree_hash/Cargo.toml +++ b/eth2/utils/cached_tree_hash/Cargo.toml @@ -4,7 +4,15 @@ version = "0.1.0" authors = ["Paul Hauner "] edition = "2018" +[profile.release] +debug = true + +[[bench]] +name = "benches" +harness = false + [dev-dependencies] +criterion = "0.2" tree_hash_derive = { path = "../tree_hash_derive" } [dependencies] diff --git a/eth2/utils/cached_tree_hash/benches/benches.rs b/eth2/utils/cached_tree_hash/benches/benches.rs new file mode 100644 index 0000000000..be7e26bb57 --- /dev/null +++ b/eth2/utils/cached_tree_hash/benches/benches.rs @@ -0,0 +1,73 @@ +#[macro_use] +extern crate criterion; + +use cached_tree_hash::TreeHashCache; +use criterion::black_box; +use criterion::{Benchmark, Criterion}; +use ethereum_types::H256 as Hash256; +use hashing::hash; +use tree_hash::TreeHash; + +fn criterion_benchmark(c: &mut Criterion) { + let n = 1024; + + let source_vec: Vec = (0..n).map(|_| Hash256::random()).collect(); + + let mut source_modified_vec = source_vec.clone(); + source_modified_vec[n - 1] = Hash256::random(); + + let modified_vec = source_modified_vec.clone(); + c.bench( + &format!("vec_of_{}_hashes", n), + Benchmark::new("standard", move |b| { + b.iter_with_setup( + || modified_vec.clone(), + |modified_vec| black_box(modified_vec.tree_hash_root()), + ) + }) + .sample_size(100), + ); + + let modified_vec = source_modified_vec.clone(); + c.bench( + &format!("vec_of_{}_hashes", n), + Benchmark::new("build_cache", move |b| { + b.iter_with_setup( + || modified_vec.clone(), + |vec| black_box(TreeHashCache::new(&vec, 0)), + ) + }) + .sample_size(100), + ); + + let vec = source_vec.clone(); + let modified_vec = source_modified_vec.clone(); + c.bench( + &format!("vec_of_{}_hashes", n), + Benchmark::new("cache_update", move |b| { + b.iter_with_setup( + || { + let cache = TreeHashCache::new(&vec, 0).unwrap(); + (cache, modified_vec.clone()) + }, + |(mut cache, modified_vec)| black_box(cache.update(&modified_vec)), + ) + }) + .sample_size(100), + ); + + c.bench( + &format!("{}_hashes", n), + Benchmark::new("hash_64_bytes", move |b| { + b.iter(|| { + for _ in 0..n { + let _digest = hash(&[42; 64]); + } + }) + }) + .sample_size(100), + ); +} + +criterion_group!(benches, criterion_benchmark); +criterion_main!(benches); diff --git a/eth2/utils/cached_tree_hash/examples/8k_hashes_cached.rs b/eth2/utils/cached_tree_hash/examples/8k_hashes_cached.rs new file mode 100644 index 0000000000..9843e12580 --- /dev/null +++ b/eth2/utils/cached_tree_hash/examples/8k_hashes_cached.rs @@ -0,0 +1,21 @@ +use cached_tree_hash::TreeHashCache; +use ethereum_types::H256 as Hash256; + +fn run(vec: &Vec, modified_vec: &Vec) { + let mut cache = TreeHashCache::new(vec, 0).unwrap(); + + cache.update(modified_vec).unwrap(); +} + +fn main() { + let n = 2048; + + let vec: Vec = (0..n).map(|_| Hash256::random()).collect(); + + let mut modified_vec = vec.clone(); + modified_vec[n - 1] = Hash256::random(); + + for _ in 0..100 { + run(&vec, &modified_vec); + } +} diff --git a/eth2/utils/cached_tree_hash/examples/8k_hashes_standard.rs b/eth2/utils/cached_tree_hash/examples/8k_hashes_standard.rs new file mode 100644 index 0000000000..e5df7ea95f --- /dev/null +++ b/eth2/utils/cached_tree_hash/examples/8k_hashes_standard.rs @@ -0,0 +1,11 @@ +use cached_tree_hash::TreeHashCache; +use ethereum_types::H256 as Hash256; +use tree_hash::TreeHash; + +fn main() { + let n = 2048; + + let vec: Vec = (0..n).map(|_| Hash256::random()).collect(); + + vec.tree_hash_root(); +}