bring back trie and triehash benches (#7926)

This commit is contained in:
Marek Kotewicz 2018-02-19 12:03:54 +01:00 committed by GitHub
parent 4bda6efed0
commit 605f3b0381
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 206 additions and 132 deletions

13
Cargo.lock generated
View File

@ -508,6 +508,7 @@ dependencies = [
"table 0.1.0",
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
"trie-standardmap 0.1.0",
"triehash 0.1.0",
"unexpected 0.1.0",
"using_queue 0.1.0",
@ -2384,6 +2385,7 @@ dependencies = [
"memorydb 0.1.1",
"rand 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rlp 0.2.1",
"trie-standardmap 0.1.0",
"triehash 0.1.0",
]
@ -3281,6 +3283,16 @@ dependencies = [
"protobuf 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "trie-standardmap"
version = "0.1.0"
dependencies = [
"ethcore-bytes 0.1.0",
"ethereum-types 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"keccak-hash 0.1.0",
"rlp 0.2.1",
]
[[package]]
name = "triehash"
version = "0.1.0"
@ -3288,6 +3300,7 @@ dependencies = [
"ethereum-types 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"keccak-hash 0.1.0",
"rlp 0.2.1",
"trie-standardmap 0.1.0",
]
[[package]]

View File

@ -70,6 +70,9 @@ unexpected = { path = "../util/unexpected" }
journaldb = { path = "../util/journaldb" }
tempdir = "0.3"
[dev-dependencies]
trie-standardmap = { path = "../util/trie-standardmap" }
[features]
jit = ["evm/jit"]
evm-debug = ["slow-blocks"]

View File

@ -17,6 +17,8 @@
//! Snapshot test helpers. These are used to build blockchains and state tries
//! which can be queried before and after a full snapshot/restore cycle.
extern crate trie_standardmap;
use std::sync::Arc;
use hash::{KECCAK_NULL_RLP};
@ -35,8 +37,8 @@ use kvdb::{KeyValueDB, DBValue};
use ethereum_types::H256;
use hashdb::HashDB;
use journaldb;
use trie::{Alphabet, StandardMap, SecTrieDBMut, TrieMut, ValueMode};
use trie::{TrieDB, TrieDBMut, Trie};
use trie::{SecTrieDBMut, TrieMut, TrieDB, TrieDBMut, Trie};
use self::trie_standardmap::{Alphabet, StandardMap, ValueMode};
// the proportion of accounts we will alter each tick.
const ACCOUNT_CHURN: f32 = 0.01;

View File

@ -17,3 +17,6 @@ rlp = { version = "0.2.1", path = "../rlp" }
triehash = { version = "0.1.0", path = "../triehash" }
memorydb = { version = "0.1.0", path = "../memorydb" }
ethcore-logger = { version = "1.9.0", path = "../../logger" }
[dev-dependencies]
trie-standardmap = { path = "../trie-standardmap" }

View File

@ -1,4 +1,4 @@
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
@ -17,23 +17,20 @@
#![feature(test)]
extern crate test;
extern crate triehash;
extern crate ethcore_util;
extern crate ethcore_bytes;
extern crate ethcore_bigint;
extern crate ethereum_types;
extern crate memorydb;
extern crate patricia_trie as trie;
#[macro_use]
extern crate log;
extern crate hash;
extern crate keccak_hash;
extern crate trie_standardmap;
use ethcore_bytes::Bytes;
use ethereum_types::H256;
use keccak_hash::keccak;
use memorydb::MemoryDB;
use test::{Bencher, black_box};
use ethcore_bigint::hash::*;
use ethcore_bytes::*;
use trie::*;
use memorydb::*;
use triehash::*;
use hash::keccak;
use trie::{TrieDBMut, TrieDB, TrieMut, Trie};
use trie_standardmap::{Alphabet, ValueMode, StandardMap};
fn random_word(alphabet: &[u8], min_count: usize, diff_count: usize, seed: &mut H256) -> Vec<u8> {
assert!(min_count + diff_count <= 32);
@ -110,21 +107,6 @@ fn trie_iter(b: &mut Bencher) {
});
}
#[bench]
fn triehash_insertions_32_mir_1k(b: &mut Bencher) {
let st = StandardMap {
alphabet: Alphabet::All,
min_key: 32,
journal_key: 0,
value_mode: ValueMode::Mirror,
count: 1000,
};
let d = st.make();
b.iter(&mut ||{
trie_root(d.clone()).clone();
});
}
#[bench]
fn trie_insertions_32_ran_1k(b: &mut Bencher) {
let st = StandardMap {
@ -147,22 +129,6 @@ fn trie_insertions_32_ran_1k(b: &mut Bencher) {
hash_count = t.hash_count;
r = t.root().clone();
});
// println!("result: {}", hash_count);
}
#[bench]
fn triehash_insertions_32_ran_1k(b: &mut Bencher) {
let st = StandardMap {
alphabet: Alphabet::All,
min_key: 32,
journal_key: 0,
value_mode: ValueMode::Random,
count: 1000,
};
let d = st.make();
b.iter(&mut ||{
trie_root(d.clone()).clone();
});
}
#[bench]
@ -185,21 +151,6 @@ fn trie_insertions_six_high(b: &mut Bencher) {
})
}
#[bench]
fn triehash_insertions_six_high(b: &mut Bencher) {
let mut d: Vec<(Bytes, Bytes)> = Vec::new();
let mut seed = H256::new();
for _ in 0..1000 {
let k = random_bytes(6, 0, &mut seed);
let v = random_value(&mut seed);
d.push((k, v))
}
b.iter(&||{
trie_root(d.clone());
})
}
#[bench]
fn trie_insertions_six_mid(b: &mut Bencher) {
let alphabet = b"@QWERTYUIOPASDFGHJKLZXCVBNM[/]^_";
@ -217,22 +168,6 @@ fn trie_insertions_six_mid(b: &mut Bencher) {
for i in d.iter() {
t.insert(&i.0, &i.1).unwrap();
}
debug!("hash_count={:?}", t.hash_count);
})
}
#[bench]
fn triehash_insertions_six_mid(b: &mut Bencher) {
let alphabet = b"@QWERTYUIOPASDFGHJKLZXCVBNM[/]^_";
let mut d: Vec<(Bytes, Bytes)> = Vec::new();
let mut seed = H256::new();
for _ in 0..1000 {
let k = random_word(alphabet, 6, 0, &mut seed);
let v = random_value(&mut seed);
d.push((k, v))
}
b.iter(||{
trie_root(d.clone());
})
}
@ -257,22 +192,6 @@ fn trie_insertions_random_mid(b: &mut Bencher) {
})
}
#[bench]
fn triehash_insertions_random_mid(b: &mut Bencher) {
let alphabet = b"@QWERTYUIOPASDFGHJKLZXCVBNM[/]^_";
let mut d: Vec<(Bytes, Bytes)> = Vec::new();
let mut seed = H256::new();
for _ in 0..1000 {
let k = random_word(alphabet, 1, 5, &mut seed);
let v = random_value(&mut seed);
d.push((k, v))
}
b.iter(||{
trie_root(d.clone());
})
}
#[bench]
fn trie_insertions_six_low(b: &mut Bencher) {
let alphabet = b"abcdef";
@ -293,29 +212,3 @@ fn trie_insertions_six_low(b: &mut Bencher) {
}
})
}
#[bench]
fn triehash_insertions_six_low(b: &mut Bencher) {
let alphabet = b"abcdef";
let mut d: Vec<(Bytes, Bytes)> = Vec::new();
let mut seed = H256::new();
for _ in 0..1000 {
let k = random_word(alphabet, 6, 0, &mut seed);
let v = random_value(&mut seed);
d.push((k, v))
}
b.iter(||{
trie_root(d.clone());
})
}
#[bench]
fn keccakx10000(b: &mut Bencher) {
b.iter(||{
let mut seed = H256::new();
for _ in 0..10000 {
seed = keccak(&seed);
}
})
}

View File

@ -25,6 +25,9 @@ extern crate elastic_array;
extern crate memorydb;
extern crate ethcore_logger;
#[cfg(test)]
extern crate trie_standardmap as standardmap;
#[macro_use]
extern crate log;
@ -33,29 +36,19 @@ use ethereum_types::H256;
use keccak::KECCAK_NULL_RLP;
use hashdb::{HashDB, DBValue};
/// Export the standardmap module.
pub mod standardmap;
/// Export the node module.
pub mod node;
/// Export the triedb module.
pub mod triedb;
/// Export the triedbmut module.
pub mod triedbmut;
/// Export the sectriedb module.
pub mod sectriedb;
/// Export the sectriedbmut module.
pub mod sectriedbmut;
/// Trie query recording.
pub mod recorder;
mod fatdb;
mod fatdbmut;
mod lookup;
mod nibbleslice;
mod nibblevec;
pub use self::standardmap::{Alphabet, StandardMap, ValueMode};
pub use self::triedbmut::TrieDBMut;
pub use self::triedb::{TrieDB, TrieDBIterator};
pub use self::sectriedbmut::SecTrieDBMut;

View File

@ -949,7 +949,7 @@ mod tests {
use bytes::ToPretty;
use keccak::KECCAK_NULL_RLP;
use super::super::TrieMut;
use super::super::standardmap::*;
use standardmap::*;
fn populate_trie<'db>(db: &'db mut HashDB, root: &'db mut H256, v: &[(Vec<u8>, Vec<u8>)]) -> TrieDBMut<'db> {
let mut t = TrieDBMut::new(db, root);

View File

@ -0,0 +1,11 @@
[package]
name = "trie-standardmap"
version = "0.1.0"
authors = ["debris <marek.kotewicz@gmail.com>"]
description = "Standard test map for profiling tries"
[dependencies]
ethcore-bytes = { path = "../bytes" }
ethereum-types = "0.2"
keccak-hash = { path = "../hash" }
rlp = { path = "../rlp" }

View File

@ -15,9 +15,15 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Key-value datastore with a modified Merkle tree.
use keccak::keccak;
use bytes::*;
extern crate ethcore_bytes as bytes;
extern crate ethereum_types;
extern crate keccak_hash;
extern crate rlp;
use bytes::Bytes;
use ethereum_types::H256;
use keccak_hash::keccak;
use rlp::encode;
/// Alphabet to use when creating words for insertion into tries.

View File

@ -9,3 +9,6 @@ license = "GPL-3.0"
rlp = { version = "0.2.1", path = "../rlp" }
ethereum-types = "0.2"
keccak-hash = { version = "0.1", path = "../hash" }
[dev-dependencies]
trie-standardmap = { path = "../trie-standardmap" }

View File

@ -0,0 +1,147 @@
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
#![feature(test)]
extern crate ethereum_types;
extern crate keccak_hash;
extern crate test;
extern crate trie_standardmap;
extern crate triehash;
use ethereum_types::H256;
use keccak_hash::keccak;
use test::Bencher;
use trie_standardmap::{Alphabet, ValueMode, StandardMap};
use triehash::trie_root;
fn random_word(alphabet: &[u8], min_count: usize, diff_count: usize, seed: &mut H256) -> Vec<u8> {
assert!(min_count + diff_count <= 32);
*seed = keccak(&seed);
let r = min_count + (seed[31] as usize % (diff_count + 1));
let mut ret: Vec<u8> = Vec::with_capacity(r);
for i in 0..r {
ret.push(alphabet[seed[i] as usize % alphabet.len()]);
}
ret
}
fn random_bytes(min_count: usize, diff_count: usize, seed: &mut H256) -> Vec<u8> {
assert!(min_count + diff_count <= 32);
*seed = keccak(&seed);
let r = min_count + (seed[31] as usize % (diff_count + 1));
seed[0..r].to_vec()
}
fn random_value(seed: &mut H256) -> Vec<u8> {
*seed = keccak(&seed);
match seed[0] % 2 {
1 => vec![seed[31];1],
_ => seed.to_vec(),
}
}
#[bench]
fn triehash_insertions_32_mir_1k(b: &mut Bencher) {
let st = StandardMap {
alphabet: Alphabet::All,
min_key: 32,
journal_key: 0,
value_mode: ValueMode::Mirror,
count: 1000,
};
let d = st.make();
b.iter(&mut ||{
trie_root(d.clone()).clone();
});
}
#[bench]
fn triehash_insertions_32_ran_1k(b: &mut Bencher) {
let st = StandardMap {
alphabet: Alphabet::All,
min_key: 32,
journal_key: 0,
value_mode: ValueMode::Random,
count: 1000,
};
let d = st.make();
b.iter(&mut ||{
trie_root(d.clone()).clone();
});
}
#[bench]
fn triehash_insertions_six_high(b: &mut Bencher) {
let mut d: Vec<(Vec<u8>, Vec<u8>)> = Vec::new();
let mut seed = H256::new();
for _ in 0..1000 {
let k = random_bytes(6, 0, &mut seed);
let v = random_value(&mut seed);
d.push((k, v))
}
b.iter(&||{
trie_root(d.clone());
})
}
#[bench]
fn triehash_insertions_six_mid(b: &mut Bencher) {
let alphabet = b"@QWERTYUIOPASDFGHJKLZXCVBNM[/]^_";
let mut d: Vec<(Vec<u8>, Vec<u8>)> = Vec::new();
let mut seed = H256::new();
for _ in 0..1000 {
let k = random_word(alphabet, 6, 0, &mut seed);
let v = random_value(&mut seed);
d.push((k, v))
}
b.iter(||{
trie_root(d.clone());
})
}
#[bench]
fn triehash_insertions_random_mid(b: &mut Bencher) {
let alphabet = b"@QWERTYUIOPASDFGHJKLZXCVBNM[/]^_";
let mut d: Vec<(Vec<u8>, Vec<u8>)> = Vec::new();
let mut seed = H256::new();
for _ in 0..1000 {
let k = random_word(alphabet, 1, 5, &mut seed);
let v = random_value(&mut seed);
d.push((k, v))
}
b.iter(||{
trie_root(d.clone());
})
}
#[bench]
fn triehash_insertions_six_low(b: &mut Bencher) {
let alphabet = b"abcdef";
let mut d: Vec<(Vec<u8>, Vec<u8>)> = Vec::new();
let mut seed = H256::new();
for _ in 0..1000 {
let k = random_word(alphabet, 6, 0, &mut seed);
let v = random_value(&mut seed);
d.push((k, v))
}
b.iter(||{
trie_root(d.clone());
})
}