diff --git a/Cargo.lock b/Cargo.lock index a1b8955df52..e7bc9cb2f30 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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]] diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index b93eb3bcc2d..a0e11ef1fe7 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -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"] diff --git a/ethcore/src/snapshot/tests/helpers.rs b/ethcore/src/snapshot/tests/helpers.rs index e45616df655..8499b990489 100644 --- a/ethcore/src/snapshot/tests/helpers.rs +++ b/ethcore/src/snapshot/tests/helpers.rs @@ -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; diff --git a/util/patricia_trie/Cargo.toml b/util/patricia_trie/Cargo.toml index be95643a18d..a1d2a9406d8 100644 --- a/util/patricia_trie/Cargo.toml +++ b/util/patricia_trie/Cargo.toml @@ -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" } diff --git a/util/benches/trie.rs b/util/patricia_trie/benches/trie.rs similarity index 67% rename from util/benches/trie.rs rename to util/patricia_trie/benches/trie.rs index 953c188838b..4e755a44d8a 100644 --- a/util/benches/trie.rs +++ b/util/patricia_trie/benches/trie.rs @@ -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 { 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); - } - }) -} diff --git a/util/patricia_trie/src/lib.rs b/util/patricia_trie/src/lib.rs index aefa1d536e5..3a1d683c26c 100644 --- a/util/patricia_trie/src/lib.rs +++ b/util/patricia_trie/src/lib.rs @@ -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; diff --git a/util/patricia_trie/src/triedbmut.rs b/util/patricia_trie/src/triedbmut.rs index 98d6c8333fc..8a3bc61f7ec 100644 --- a/util/patricia_trie/src/triedbmut.rs +++ b/util/patricia_trie/src/triedbmut.rs @@ -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, Vec)]) -> TrieDBMut<'db> { let mut t = TrieDBMut::new(db, root); diff --git a/util/trie-standardmap/Cargo.toml b/util/trie-standardmap/Cargo.toml new file mode 100644 index 00000000000..caa915c542a --- /dev/null +++ b/util/trie-standardmap/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "trie-standardmap" +version = "0.1.0" +authors = ["debris "] +description = "Standard test map for profiling tries" + +[dependencies] +ethcore-bytes = { path = "../bytes" } +ethereum-types = "0.2" +keccak-hash = { path = "../hash" } +rlp = { path = "../rlp" } diff --git a/util/patricia_trie/src/standardmap.rs b/util/trie-standardmap/src/lib.rs similarity index 96% rename from util/patricia_trie/src/standardmap.rs rename to util/trie-standardmap/src/lib.rs index d71f1ee3727..d7ee08ac46c 100644 --- a/util/patricia_trie/src/standardmap.rs +++ b/util/trie-standardmap/src/lib.rs @@ -15,9 +15,15 @@ // along with Parity. If not, see . //! 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. diff --git a/util/triehash/Cargo.toml b/util/triehash/Cargo.toml index 16678275a99..c7b62423746 100644 --- a/util/triehash/Cargo.toml +++ b/util/triehash/Cargo.toml @@ -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" } diff --git a/util/triehash/benches/triehash.rs b/util/triehash/benches/triehash.rs new file mode 100644 index 00000000000..505ea1223d9 --- /dev/null +++ b/util/triehash/benches/triehash.rs @@ -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 . + +#![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 { + assert!(min_count + diff_count <= 32); + *seed = keccak(&seed); + let r = min_count + (seed[31] as usize % (diff_count + 1)); + let mut ret: Vec = 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 { + 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 { + *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, Vec)> = 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, Vec)> = 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, Vec)> = 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, Vec)> = 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()); + }) +}