dedicated bencer
This commit is contained in:
parent
01f895cc08
commit
b19408a0a8
|
@ -64,6 +64,19 @@ name = "base58"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bencher"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"chain 0.1.0",
|
||||||
|
"db 0.1.0",
|
||||||
|
"ethcore-devtools 1.3.0",
|
||||||
|
"primitives 0.1.0",
|
||||||
|
"test-data 0.1.0",
|
||||||
|
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"verification 0.1.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bit-vec"
|
name = "bit-vec"
|
||||||
version = "0.4.3"
|
version = "0.4.3"
|
||||||
|
@ -482,6 +495,7 @@ name = "pbtc"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"app_dirs 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"app_dirs 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"bencher 0.1.0",
|
||||||
"chain 0.1.0",
|
"chain 0.1.0",
|
||||||
"clap 2.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"clap 2.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"db 0.1.0",
|
"db 0.1.0",
|
||||||
|
|
|
@ -20,6 +20,7 @@ db = { path = "db" }
|
||||||
verification = { path = "verification" }
|
verification = { path = "verification" }
|
||||||
sync = { path = "sync" }
|
sync = { path = "sync" }
|
||||||
import = { path = "import" }
|
import = { path = "import" }
|
||||||
|
bencher = { path = "bencher" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
path = "pbtc/main.rs"
|
path = "pbtc/main.rs"
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
[package]
|
||||||
|
name = "bencher"
|
||||||
|
version = "0.1.0"
|
||||||
|
license = "GPL-3.0"
|
||||||
|
authors = ["Ethcore <admin@ethcore.io>"]
|
||||||
|
description = "Parity bitcoin client."
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
db = { path = "../db" }
|
||||||
|
verification = { path = "../verification" }
|
||||||
|
chain = { path = "../chain" }
|
||||||
|
primitives = { path = "../primitives" }
|
||||||
|
ethcore-devtools = { path = "../devtools" }
|
||||||
|
test-data = { path = "../test-data" }
|
||||||
|
time = "*"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
path = "src/main.rs"
|
||||||
|
name = "bencher"
|
|
@ -0,0 +1,145 @@
|
||||||
|
use devtools::RandomTempPath;
|
||||||
|
use db::{Storage, BlockStapler, BlockProvider, BlockRef, BlockInsertedChain};
|
||||||
|
use test_data;
|
||||||
|
|
||||||
|
use super::Benchmark;
|
||||||
|
|
||||||
|
pub fn fetch(benchmark: &mut Benchmark) {
|
||||||
|
// params
|
||||||
|
const BLOCKS: usize = 10000;
|
||||||
|
|
||||||
|
// test setup
|
||||||
|
let path = RandomTempPath::create_dir();
|
||||||
|
let store = Storage::new(path.as_path()).unwrap();
|
||||||
|
|
||||||
|
let genesis = test_data::genesis();
|
||||||
|
store.insert_block(&genesis).unwrap();
|
||||||
|
|
||||||
|
let genesis = test_data::genesis();
|
||||||
|
store.insert_block(&genesis).unwrap();
|
||||||
|
|
||||||
|
let mut rolling_hash = genesis.hash();
|
||||||
|
let mut blocks = Vec::new();
|
||||||
|
let mut hashes = Vec::new();
|
||||||
|
|
||||||
|
for x in 0..BLOCKS {
|
||||||
|
let next_block = test_data::block_builder()
|
||||||
|
.transaction().coinbase().build()
|
||||||
|
.transaction().output().value(5000000000).build().build()
|
||||||
|
.merkled_header().parent(rolling_hash.clone()).nonce(x as u32).build()
|
||||||
|
.build();
|
||||||
|
rolling_hash = next_block.hash();
|
||||||
|
blocks.push(next_block);
|
||||||
|
hashes.push(rolling_hash.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
for block in blocks.iter() { store.insert_block(block).unwrap(); }
|
||||||
|
|
||||||
|
// bench
|
||||||
|
benchmark.start();
|
||||||
|
for _ in 0..BLOCKS {
|
||||||
|
let block = store.block(BlockRef::Hash(hashes[0].clone())).unwrap();
|
||||||
|
assert_eq!(&block.hash(), &hashes[0]);
|
||||||
|
}
|
||||||
|
benchmark.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write(benchmark: &mut Benchmark) {
|
||||||
|
// params
|
||||||
|
const BLOCKS: usize = 1000;
|
||||||
|
|
||||||
|
// setup
|
||||||
|
let path = RandomTempPath::create_dir();
|
||||||
|
let store = Storage::new(path.as_path()).unwrap();
|
||||||
|
|
||||||
|
let genesis = test_data::genesis();
|
||||||
|
store.insert_block(&genesis).unwrap();
|
||||||
|
|
||||||
|
let mut rolling_hash = genesis.hash();
|
||||||
|
|
||||||
|
let mut blocks = Vec::new();
|
||||||
|
|
||||||
|
for x in 0..BLOCKS {
|
||||||
|
let next_block = test_data::block_builder()
|
||||||
|
.transaction().coinbase().build()
|
||||||
|
.transaction().output().value(5000000000).build().build()
|
||||||
|
.merkled_header().parent(rolling_hash.clone()).nonce(x as u32).build()
|
||||||
|
.build();
|
||||||
|
rolling_hash = next_block.hash();
|
||||||
|
blocks.push(next_block);
|
||||||
|
}
|
||||||
|
|
||||||
|
// bench
|
||||||
|
benchmark.start();
|
||||||
|
for idx in 0..BLOCKS {
|
||||||
|
store.insert_block(&blocks[idx]).unwrap();
|
||||||
|
}
|
||||||
|
benchmark.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reorg_short(benchmark: &mut Benchmark) {
|
||||||
|
// params
|
||||||
|
const BLOCKS: usize = 1000;
|
||||||
|
|
||||||
|
// setup
|
||||||
|
let path = RandomTempPath::create_dir();
|
||||||
|
let store = Storage::new(path.as_path()).unwrap();
|
||||||
|
|
||||||
|
let genesis = test_data::genesis();
|
||||||
|
store.insert_block(&genesis).unwrap();
|
||||||
|
|
||||||
|
let mut rolling_hash = genesis.hash();
|
||||||
|
|
||||||
|
let mut blocks = Vec::new();
|
||||||
|
|
||||||
|
for x in 0..1000 {
|
||||||
|
let base = rolling_hash.clone();
|
||||||
|
|
||||||
|
let next_block = test_data::block_builder()
|
||||||
|
.transaction().coinbase().build()
|
||||||
|
.transaction().output().value(5000000000).build().build()
|
||||||
|
.merkled_header().parent(rolling_hash.clone()).nonce(x*4).build()
|
||||||
|
.build();
|
||||||
|
rolling_hash = next_block.hash();
|
||||||
|
blocks.push(next_block);
|
||||||
|
|
||||||
|
let next_block_side = test_data::block_builder()
|
||||||
|
.transaction().coinbase().build()
|
||||||
|
.transaction().output().value(5000000000).build().build()
|
||||||
|
.merkled_header().parent(base).nonce(x * 4 + 2).build()
|
||||||
|
.build();
|
||||||
|
let next_base = next_block_side.hash();
|
||||||
|
blocks.push(next_block_side);
|
||||||
|
|
||||||
|
let next_block_side_continue = test_data::block_builder()
|
||||||
|
.transaction().coinbase().build()
|
||||||
|
.transaction().output().value(5000000000).build().build()
|
||||||
|
.merkled_header().parent(next_base).nonce(x * 4 + 3).build()
|
||||||
|
.build();
|
||||||
|
blocks.push(next_block_side_continue);
|
||||||
|
|
||||||
|
let next_block_continue = test_data::block_builder()
|
||||||
|
.transaction().coinbase().build()
|
||||||
|
.transaction().output().value(5000000000).build().build()
|
||||||
|
.merkled_header().parent(rolling_hash.clone()).nonce(x * 4+1).build()
|
||||||
|
.build();
|
||||||
|
rolling_hash = next_block_continue.hash();
|
||||||
|
blocks.push(next_block_continue);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut total: usize = 0;
|
||||||
|
let mut reorgs: usize = 0;
|
||||||
|
|
||||||
|
// bench
|
||||||
|
benchmark.start();
|
||||||
|
for idx in 0..BLOCKS {
|
||||||
|
total += 1;
|
||||||
|
if let BlockInsertedChain::Reorganized(_) = store.insert_block(&blocks[idx]).unwrap() {
|
||||||
|
reorgs += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
benchmark.stop();
|
||||||
|
|
||||||
|
assert_eq!(1000, total);
|
||||||
|
assert_eq!(499, reorgs);
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
extern crate db;
|
||||||
|
extern crate chain;
|
||||||
|
extern crate ethcore_devtools as devtools;
|
||||||
|
extern crate test_data;
|
||||||
|
extern crate time;
|
||||||
|
|
||||||
|
mod database;
|
||||||
|
|
||||||
|
use time::{PreciseTime, Duration};
|
||||||
|
use std::io::Write;
|
||||||
|
use std::str;
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct Benchmark {
|
||||||
|
start: Option<PreciseTime>,
|
||||||
|
end: Option<PreciseTime>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Benchmark {
|
||||||
|
pub fn start(&mut self) {
|
||||||
|
self.start = Some(PreciseTime::now());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn stop(&mut self) {
|
||||||
|
self.end = Some(PreciseTime::now());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn evaluate(&self) -> Duration {
|
||||||
|
self.start.expect("benchmarch never ended").to(self.end.expect("benchmark never started"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn decimal_mark(s: String) -> String {
|
||||||
|
let bytes: Vec<_> = s.bytes().rev().collect();
|
||||||
|
let chunks: Vec<_> = bytes.chunks(3).map(|chunk| str::from_utf8(chunk).unwrap()).collect();
|
||||||
|
let result: Vec<_> = chunks.join(",").bytes().rev().collect();
|
||||||
|
String::from_utf8(result).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn run_benchmark<F>(name: &str, f: F) where F: FnOnce(&mut Benchmark) {
|
||||||
|
print!("{}: ", name);
|
||||||
|
::std::io::stdout().flush().unwrap();
|
||||||
|
|
||||||
|
let mut benchmark = Benchmark::default();
|
||||||
|
f(&mut benchmark);
|
||||||
|
println!("{} ns", decimal_mark(format!("{}", benchmark.evaluate().num_nanoseconds().unwrap())));
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! benchmark {
|
||||||
|
($t:expr) => {
|
||||||
|
run_benchmark(stringify!($t), $t);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
benchmark!(database::fetch);
|
||||||
|
benchmark!(database::write);
|
||||||
|
benchmark!(database::reorg_short);
|
||||||
|
}
|
Loading…
Reference in New Issue