Skip to content

Commit

Permalink
benchmarks: move all benchmarks to their own file
Browse files Browse the repository at this point in the history
By having everything in one file it reduces clutter in the codebase,
will make it easier to unify benchmark-generation code, and (IMO most
importantly) lets you write `cargo bench benchmarks` and then it'll only
run the benchmarks instead of outputting a gazillion "ignored" lines
telling you that it's not benchmarking random shit that aren't
benchmarks.

Don't re-format stuff so it'll be obvious in the diff that this is a
pure code move. Also we are going to rewrite the benchmarks in the next
commit anyway.
  • Loading branch information
apoelstra committed Sep 8, 2024
1 parent 5d54ee3 commit 532d0fa
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 130 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ please join us in
## Benchmarks

We use a custom Rust compiler configuration conditional to guard the bench mark code. To run the
bench marks use: `RUSTFLAGS='--cfg=bench' cargo +nightly bench`.
benchmarks use: `RUSTFLAGS='--cfg=bench' cargo +nightly bench benchmarks`.


## Release Notes
Expand Down
2 changes: 1 addition & 1 deletion justfile
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ fmt-check:

# Run the benchmark suite.
bench:
RUSTFLAGS='--cfg=bench' cargo +nightly bench
RUSTFLAGS='--cfg=bench' cargo +nightly bench benchmarks

# Build the docs (same as for docs.rs).
docsrs:
Expand Down
122 changes: 122 additions & 0 deletions src/benchmarks.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
// Written in 2019 by Andrew Poelstra <[email protected]>
// SPDX-License-Identifier: CC0-1.0

//! Benchmarks
//!
//! Benchmarks using the built-in rustc benchmark infrastructure. Requires a
//! nightly compiler to run. See the README for exact instructions.
//!
use test::{black_box, Bencher};

use crate::expression::Tree;
use crate::miniscript::context;
use crate::{Miniscript, ExtParams};

#[bench]
pub fn parse_segwit0(bh: &mut Bencher) {
bh.iter(|| {
let tree = Miniscript::<String, context::Segwitv0>::from_str_ext(
"and_v(v:pk(E),thresh(2,j:and_v(v:sha256(H),t:or_i(v:sha256(H),v:pkh(A))),s:pk(B),s:pk(C),s:pk(D),sjtv:sha256(H)))",
&ExtParams::sane(),
).unwrap();
black_box(tree);
});
}

#[bench]
pub fn parse_segwit0_deep(bh: &mut Bencher) {
bh.iter(|| {
let tree = Miniscript::<String, context::Segwitv0>::from_str_ext(
"and_v(v:and_v(v:and_v(v:and_v(v:and_v(v:and_v(v:and_v(v:and_v(v:and_v(v:and_v(v:and_v(v:and_v(v:and_v(v:and_v(v:and_v(v:and_v(v:and_v(v:and_v(v:and_v(v:and_v(v:pk(1),pk(2)),pk(3)),pk(4)),pk(5)),pk(6)),pk(7)),pk(8)),pk(9)),pk(10)),pk(11)),pk(12)),pk(13)),pk(14)),pk(15)),pk(16)),pk(17)),pk(18)),pk(19)),pk(20)),pk(21))",
&ExtParams::sane(),
).unwrap();
black_box(tree);
});
}

#[bench]
pub fn parse_tree(bh: &mut Bencher) {
bh.iter(|| {
let tree = Tree::from_str(
"and(thresh(2,and(sha256(H),or(sha256(H),pk(A))),pk(B),pk(C),pk(D),sha256(H)),pk(E))",
).unwrap();
black_box(tree);
});
}

#[bench]
pub fn parse_tree_deep(bh: &mut Bencher) {
bh.iter(|| {
let tree = Tree::from_str(
"and(and(and(and(and(and(and(and(and(and(and(and(and(and(and(and(and(and(and(and(1,2),3),4),5),6),7),8),9),10),11),12),13),14),15),16),17),18),19),20),21)"
).unwrap();
black_box(tree);
});
}

#[cfg(feature = "compiler")]
mod compiler_benches {
use super::*;

use core::str::FromStr;

use crate::Error;
use crate::policy::Concrete;
use crate::policy::compiler::CompilerError;
use crate::descriptor::Descriptor;
use crate::miniscript::Tap;
use crate::prelude::*;

type TapMsRes = Result<Miniscript<String, Tap>, CompilerError>;
type TapDesc = Result<Descriptor<String>, Error>;

#[bench]
pub fn compile_large_tap(bh: &mut Bencher) {
let pol = Concrete::<String>::from_str(
"thresh(20,pk(A),pk(B),pk(C),pk(D),pk(E),pk(F),pk(G),pk(H),pk(I),pk(J),pk(K),pk(L),pk(M),pk(N),pk(O),pk(P),pk(Q),pk(R),pk(S),pk(T),pk(U),pk(V),pk(W),pk(X),pk(Y),pk(Z))",
)
.expect("parsing");
bh.iter(|| {
let pt: TapDesc = pol.compile_tr_private_experimental(Some("UNSPEND".to_string()));
black_box(pt).unwrap();
});
}

#[bench]
pub fn compile_basic(bh: &mut Bencher) {
let h = (0..64).map(|_| "a").collect::<String>();
let pol = Concrete::<String>::from_str(&format!(
"and(thresh(2,and(sha256({}),or(sha256({}),pk(A))),pk(B),pk(C),pk(D),sha256({})),pk(E))",
h, h, h
))
.expect("parsing");
bh.iter(|| {
let pt: TapMsRes = pol.compile();
black_box(pt).unwrap();
});
}

#[bench]
pub fn compile_large(bh: &mut Bencher) {
let h = (0..64).map(|_| "a").collect::<String>();
let pol = Concrete::<String>::from_str(
&format!("or(pk(L),thresh(9,sha256({}),pk(A),pk(B),and(or(pk(C),pk(D)),pk(E)),after(100),pk(F),pk(G),pk(H),pk(I),and(pk(J),pk(K))))", h)
).expect("parsing");
bh.iter(|| {
let pt: TapMsRes = pol.compile();
black_box(pt).unwrap();
});
}

#[bench]
pub fn compile_xlarge(bh: &mut Bencher) {
let pol = Concrete::<String>::from_str(
"or(pk(A),thresh(4,pk(B),older(100),pk(C),and(after(100),or(pk(D),or(pk(E),and(pk(F),thresh(2,pk(G),or(pk(H),and(thresh(5,pk(I),or(pk(J),pk(K)),pk(L),pk(M),pk(N),pk(O),pk(P),pk(Q),pk(R),pk(S),pk(T)),pk(U))),pk(V),or(and(pk(W),pk(X)),pk(Y)),after(100)))))),pk(Z)))"
).expect("parsing");
bh.iter(|| {
let pt: TapMsRes = pol.compile();
black_box(pt).unwrap();
});
}
}
26 changes: 0 additions & 26 deletions src/expression/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,29 +315,3 @@ mod tests {
}
}

#[cfg(bench)]
mod benches {
use test::{black_box, Bencher};

use super::*;

#[bench]
pub fn parse_tree(bh: &mut Bencher) {
bh.iter(|| {
let tree = Tree::from_str(
"and(thresh(2,and(sha256(H),or(sha256(H),pk(A))),pk(B),pk(C),pk(D),sha256(H)),pk(E))",
).unwrap();
black_box(tree);
});
}

#[bench]
pub fn parse_tree_deep(bh: &mut Bencher) {
bh.iter(|| {
let tree = Tree::from_str(
"and(and(and(and(and(and(and(and(and(and(and(and(and(and(and(and(and(and(and(and(1,2),3),4),5),6),7),8),9),10),11),12),13),14),15),16),17),18),19),20),21)"
).unwrap();
black_box(tree);
});
}
}
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ mod macros;
#[macro_use]
mod pub_macros;

#[cfg(bench)]
mod benchmarks;
mod blanket_traits;
pub mod descriptor;
pub mod expression;
Expand Down
29 changes: 0 additions & 29 deletions src/miniscript/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1635,32 +1635,3 @@ mod tests {
Tapscript::parse_insane(&script.into_script()).unwrap_err();
}
}

#[cfg(bench)]
mod benches {
use test::{black_box, Bencher};

use super::*;

#[bench]
pub fn parse_segwit0(bh: &mut Bencher) {
bh.iter(|| {
let tree = Miniscript::<String, context::Segwitv0>::from_str_ext(
"and_v(v:pk(E),thresh(2,j:and_v(v:sha256(H),t:or_i(v:sha256(H),v:pkh(A))),s:pk(B),s:pk(C),s:pk(D),sjtv:sha256(H)))",
&ExtParams::sane(),
).unwrap();
black_box(tree);
});
}

#[bench]
pub fn parse_segwit0_deep(bh: &mut Bencher) {
bh.iter(|| {
let tree = Miniscript::<String, context::Segwitv0>::from_str_ext(
"and_v(v:and_v(v:and_v(v:and_v(v:and_v(v:and_v(v:and_v(v:and_v(v:and_v(v:and_v(v:and_v(v:and_v(v:and_v(v:and_v(v:and_v(v:and_v(v:and_v(v:and_v(v:and_v(v:and_v(v:pk(1),pk(2)),pk(3)),pk(4)),pk(5)),pk(6)),pk(7)),pk(8)),pk(9)),pk(10)),pk(11)),pk(12)),pk(13)),pk(14)),pk(15)),pk(16)),pk(17)),pk(18)),pk(19)),pk(20)),pk(21))",
&ExtParams::sane(),
).unwrap();
black_box(tree);
});
}
}
49 changes: 0 additions & 49 deletions src/policy/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1649,52 +1649,3 @@ mod tests {
}
}
}

#[cfg(bench)]
mod benches {
use std::str::FromStr;

use test::{black_box, Bencher};

use super::{CompilerError, Concrete};
use crate::miniscript::Tap;
use crate::prelude::*;
use crate::Miniscript;
type TapMsRes = Result<Miniscript<String, Tap>, CompilerError>;
#[bench]
pub fn compile_basic(bh: &mut Bencher) {
let h = (0..64).map(|_| "a").collect::<String>();
let pol = Concrete::<String>::from_str(&format!(
"and(thresh(2,and(sha256({}),or(sha256({}),pk(A))),pk(B),pk(C),pk(D),sha256({})),pk(E))",
h, h, h
))
.expect("parsing");
bh.iter(|| {
let pt: TapMsRes = pol.compile();
black_box(pt).unwrap();
});
}

#[bench]
pub fn compile_large(bh: &mut Bencher) {
let h = (0..64).map(|_| "a").collect::<String>();
let pol = Concrete::<String>::from_str(
&format!("or(pk(L),thresh(9,sha256({}),pk(A),pk(B),and(or(pk(C),pk(D)),pk(E)),after(100),pk(F),pk(G),pk(H),pk(I),and(pk(J),pk(K))))", h)
).expect("parsing");
bh.iter(|| {
let pt: TapMsRes = pol.compile();
black_box(pt).unwrap();
});
}

#[bench]
pub fn compile_xlarge(bh: &mut Bencher) {
let pol = Concrete::<String>::from_str(
"or(pk(A),thresh(4,pk(B),older(100),pk(C),and(after(100),or(pk(D),or(pk(E),and(pk(F),thresh(2,pk(G),or(pk(H),and(thresh(5,pk(I),or(pk(J),pk(K)),pk(L),pk(M),pk(N),pk(O),pk(P),pk(Q),pk(R),pk(S),pk(T)),pk(U))),pk(V),or(and(pk(W),pk(X)),pk(Y)),after(100)))))),pk(Z)))"
).expect("parsing");
bh.iter(|| {
let pt: TapMsRes = pol.compile();
black_box(pt).unwrap();
});
}
}
24 changes: 0 additions & 24 deletions src/policy/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -539,27 +539,3 @@ mod tests {
}
}
}

#[cfg(all(bench, feature = "compiler"))]
mod benches {
use core::str::FromStr;

use test::{black_box, Bencher};

use super::{Concrete, Error};
use crate::descriptor::Descriptor;
use crate::prelude::*;
type TapDesc = Result<Descriptor<String>, Error>;

#[bench]
pub fn compile_large_tap(bh: &mut Bencher) {
let pol = Concrete::<String>::from_str(
"thresh(20,pk(A),pk(B),pk(C),pk(D),pk(E),pk(F),pk(G),pk(H),pk(I),pk(J),pk(K),pk(L),pk(M),pk(N),pk(O),pk(P),pk(Q),pk(R),pk(S),pk(T),pk(U),pk(V),pk(W),pk(X),pk(Y),pk(Z))",
)
.expect("parsing");
bh.iter(|| {
let pt: TapDesc = pol.compile_tr_private_experimental(Some("UNSPEND".to_string()));
black_box(pt).unwrap();
});
}
}

0 comments on commit 532d0fa

Please sign in to comment.