Skip to content

Commit 2e49013

Browse files
remagpieforiequal0
authored andcommitted
Add benchmark tests for util/merkle
1 parent 62d8912 commit 2e49013

File tree

3 files changed

+174
-5
lines changed

3 files changed

+174
-5
lines changed

Cargo.lock

Lines changed: 9 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

util/merkle/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,9 @@ primitives = { git = "https://github.com/CodeChain-io/rust-codechain-primitives.
1212
rlp = {path = "../rlp" }
1313

1414
[dev-dependencies]
15+
journaldb = { path = "../journaldb" }
16+
kvdb = { path = "../kvdb" }
17+
kvdb-rocksdb = { path = "../kvdb-rocksdb" }
18+
tempfile = "3.1.0"
1519
trie-standardmap = { path = "../trie-standardmap" }
1620
memorydb = {path = "../memorydb" }

util/merkle/benches/triedb.rs

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
// Copyright 2019 Kodebox, Inc.
2+
// This file is part of CodeChain.
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Affero General Public License as
6+
// published by the Free Software Foundation, either version 3 of the
7+
// License, or (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Affero General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Affero General Public License
15+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
17+
#![feature(test)]
18+
19+
extern crate codechain_merkle as cmerkle;
20+
extern crate hashdb;
21+
extern crate journaldb;
22+
extern crate kvdb;
23+
extern crate kvdb_rocksdb as rocksdb;
24+
extern crate primitives;
25+
extern crate rand;
26+
extern crate tempfile;
27+
extern crate test;
28+
29+
use std::path::Path;
30+
use std::sync::Arc;
31+
32+
use cmerkle::{Trie, TrieDB, TrieDBMut, TrieMut};
33+
use kvdb::DBTransaction;
34+
use primitives::H256;
35+
use rand::random;
36+
use rocksdb::{CompactionProfile, Database, DatabaseConfig};
37+
use tempfile::{tempdir, TempDir};
38+
use test::Bencher;
39+
40+
struct TestDB {
41+
_dir: TempDir,
42+
db: Arc<Database>,
43+
journal: Box<dyn journaldb::JournalDB>,
44+
root: H256,
45+
}
46+
47+
impl TestDB {
48+
// Replicate CodeChain's db config
49+
fn config(path: &Path) -> DatabaseConfig {
50+
let mut config = DatabaseConfig::with_columns(Some(1));
51+
config.memory_budget = Default::default();
52+
config.compaction = CompactionProfile::auto(path);
53+
config.wal = true;
54+
config
55+
}
56+
57+
fn populate(path: &Path, size: usize) -> H256 {
58+
// Create database
59+
let config = Self::config(path);
60+
let db = Arc::new(Database::open(&config, path.to_str().unwrap()).unwrap());
61+
let mut journal = journaldb::new(db.clone(), journaldb::Algorithm::Archive, Some(0));
62+
let mut root = H256::new();
63+
{
64+
let hashdb = journal.as_hashdb_mut();
65+
let mut trie = TrieDBMut::new(hashdb, &mut root);
66+
for i in 0..size {
67+
trie.insert(&i.to_be_bytes(), &i.to_be_bytes()).unwrap();
68+
}
69+
}
70+
let mut batch = DBTransaction::new();
71+
journal.journal_under(&mut batch, 0, &H256::new()).unwrap();
72+
db.write_buffered(batch);
73+
db.flush().unwrap();
74+
75+
root
76+
}
77+
78+
fn new(size: usize) -> Self {
79+
// Create temporary directory
80+
let dir = tempdir().unwrap();
81+
let root = Self::populate(dir.path(), size);
82+
83+
// Create database
84+
let config = Self::config(dir.path());
85+
let db = Arc::new(Database::open(&config, dir.path().to_str().unwrap()).unwrap());
86+
let journal = journaldb::new(db.clone(), journaldb::Algorithm::Archive, Some(0));
87+
88+
Self {
89+
_dir: dir,
90+
db,
91+
journal,
92+
root,
93+
}
94+
}
95+
96+
fn trie(&self) -> TrieDB {
97+
let hashdb = self.journal.as_hashdb();
98+
TrieDB::try_new(hashdb, &self.root).unwrap()
99+
}
100+
101+
fn trie_mut(&mut self) -> TrieDBMut {
102+
let hashdb = self.journal.as_hashdb_mut();
103+
TrieDBMut::new(hashdb, &mut self.root)
104+
}
105+
106+
fn flush(&mut self) {
107+
let mut batch = DBTransaction::new();
108+
self.journal.journal_under(&mut batch, 0, &H256::new()).unwrap();
109+
self.db.write_buffered(batch);
110+
self.db.flush().unwrap();
111+
}
112+
}
113+
114+
const DB_SIZE: usize = 10000;
115+
const BATCH: usize = 10000;
116+
117+
#[bench]
118+
fn bench_read_single(b: &mut Bencher) {
119+
let db = TestDB::new(DB_SIZE);
120+
b.iter(|| {
121+
let trie = db.trie();
122+
let item = random::<usize>() % DB_SIZE;
123+
let _ = trie.get(&item.to_be_bytes()).unwrap().unwrap();
124+
});
125+
}
126+
127+
#[bench]
128+
fn bench_read_multiple(b: &mut Bencher) {
129+
let db = TestDB::new(DB_SIZE);
130+
b.iter(|| {
131+
let trie = db.trie();
132+
for _ in 0..BATCH {
133+
let item = random::<usize>() % DB_SIZE;
134+
let _ = trie.get(&item.to_be_bytes()).unwrap().unwrap();
135+
}
136+
});
137+
}
138+
139+
#[bench]
140+
fn bench_write_single(b: &mut Bencher) {
141+
let mut db = TestDB::new(DB_SIZE);
142+
b.iter(|| {
143+
let mut trie = db.trie_mut();
144+
let item = random::<usize>() % DB_SIZE + DB_SIZE;
145+
let _ = trie.insert(&item.to_be_bytes(), &item.to_be_bytes()).unwrap();
146+
db.flush();
147+
});
148+
}
149+
150+
#[bench]
151+
fn bench_write_multiple(b: &mut Bencher) {
152+
let mut db = TestDB::new(DB_SIZE);
153+
b.iter(|| {
154+
let mut trie = db.trie_mut();
155+
for _ in 0..BATCH {
156+
let item = random::<usize>() % DB_SIZE + DB_SIZE;
157+
let _ = trie.insert(&item.to_be_bytes(), &item.to_be_bytes()).unwrap();
158+
}
159+
db.flush();
160+
});
161+
}

0 commit comments

Comments
 (0)