From 532d0fa43499ff7ee6ca5c6cb9592a9e8fc0b056 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Sun, 8 Sep 2024 13:08:55 +0000 Subject: [PATCH] benchmarks: move all benchmarks to their own file 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. --- README.md | 2 +- justfile | 2 +- src/benchmarks.rs | 122 +++++++++++++++++++++++++++++++++++++++++ src/expression/mod.rs | 26 --------- src/lib.rs | 2 + src/miniscript/mod.rs | 29 ---------- src/policy/compiler.rs | 49 ----------------- src/policy/mod.rs | 24 -------- 8 files changed, 126 insertions(+), 130 deletions(-) create mode 100644 src/benchmarks.rs diff --git a/README.md b/README.md index 6e638ff2a..d403352d4 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/justfile b/justfile index 7190407ab..56fcb3da5 100644 --- a/justfile +++ b/justfile @@ -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: diff --git a/src/benchmarks.rs b/src/benchmarks.rs new file mode 100644 index 000000000..6e4534eba --- /dev/null +++ b/src/benchmarks.rs @@ -0,0 +1,122 @@ +// Written in 2019 by Andrew Poelstra +// 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::::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::::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, CompilerError>; + type TapDesc = Result, Error>; + + #[bench] + pub fn compile_large_tap(bh: &mut Bencher) { + let pol = Concrete::::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::(); + let pol = Concrete::::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::(); + let pol = Concrete::::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::::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(); + }); + } +} diff --git a/src/expression/mod.rs b/src/expression/mod.rs index 06c4fa6bb..bded57712 100644 --- a/src/expression/mod.rs +++ b/src/expression/mod.rs @@ -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); - }); - } -} diff --git a/src/lib.rs b/src/lib.rs index 63885ab75..51867bda4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -113,6 +113,8 @@ mod macros; #[macro_use] mod pub_macros; +#[cfg(bench)] +mod benchmarks; mod blanket_traits; pub mod descriptor; pub mod expression; diff --git a/src/miniscript/mod.rs b/src/miniscript/mod.rs index f5ca05fdb..13195d7f9 100644 --- a/src/miniscript/mod.rs +++ b/src/miniscript/mod.rs @@ -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::::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::::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); - }); - } -} diff --git a/src/policy/compiler.rs b/src/policy/compiler.rs index 63e16579e..45bd1d3a6 100644 --- a/src/policy/compiler.rs +++ b/src/policy/compiler.rs @@ -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, CompilerError>; - #[bench] - pub fn compile_basic(bh: &mut Bencher) { - let h = (0..64).map(|_| "a").collect::(); - let pol = Concrete::::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::(); - let pol = Concrete::::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::::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(); - }); - } -} diff --git a/src/policy/mod.rs b/src/policy/mod.rs index de9577e68..974516dac 100644 --- a/src/policy/mod.rs +++ b/src/policy/mod.rs @@ -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, Error>; - - #[bench] - pub fn compile_large_tap(bh: &mut Bencher) { - let pol = Concrete::::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(); - }); - } -}