Skip to content

Commit ecf71a8

Browse files
authored
Merge pull request #827 from sethdusek/criterion
Add criterion benchmarks
2 parents 2dcbfdc + b3a9bda commit ecf71a8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+469
-95
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ proptest-derive = "0.5.1"
100100
pretty_assertions = "1.3"
101101
wasm-bindgen-test = "0.3.37"
102102
expect-test = "1.4.1"
103+
criterion = { version = "0.5.1", features = ["default", "cargo_bench_support"] }
103104

104105
[profile.release]
105106
# Tell `rustc` to optimize for small code size.

ergo-lib/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,12 @@ sigma-test-util = { workspace = true }
7777
pretty_assertions = { workspace = true }
7878
bs58 = { workspace = true }
7979
expect-test = { workspace = true }
80+
criterion = { workspace = true }
8081

82+
[[bench]]
83+
name = "tx_context"
84+
harness = false
85+
required-features = ["arbitrary"]
8186

8287
# docs.rs-specific configuration
8388
[package.metadata.docs.rs]

ergo-lib/benches/tx_context.rs

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
use criterion::{criterion_group, criterion_main, BatchSize};
2+
3+
use criterion::{BenchmarkId, Criterion, SamplingMode};
4+
use ergo_lib::chain::ergo_box::box_builder::ErgoBoxCandidateBuilder;
5+
use ergo_lib::{
6+
chain::transaction::{unsigned::UnsignedTransaction, UnsignedInput},
7+
wallet::{secret_key::SecretKey, signing::TransactionContext, Wallet},
8+
};
9+
use ergotree_ir::chain::ergo_box::box_value::BoxValue;
10+
use ergotree_ir::chain::tx_id::TxId;
11+
use ergotree_ir::mir::expr::Expr;
12+
use ergotree_ir::{
13+
chain::{context_extension::ContextExtension, ergo_box::ErgoBox},
14+
ergo_tree::{ErgoTree, ErgoTreeHeader},
15+
mir::constant::Constant,
16+
};
17+
use sigma_test_util::force_any_val;
18+
19+
pub fn bench_tx_context(c: &mut Criterion) {
20+
let mut group = c.benchmark_group("TransactionContext::new scaling with inputs");
21+
group.sample_size(10);
22+
let true_tree = ErgoTree::new(ErgoTreeHeader::v0(true), &Expr::Const(true.into())).unwrap();
23+
24+
for range in (1..=100).step_by(10) {
25+
let inputs = (0..range)
26+
.map(|i| {
27+
ErgoBox::from_box_candidate(
28+
&ErgoBoxCandidateBuilder::new(BoxValue::SAFE_USER_MIN, true_tree.clone(), 1000)
29+
.build()
30+
.unwrap(),
31+
TxId::zero(),
32+
i as u16,
33+
)
34+
.unwrap()
35+
})
36+
.collect::<Vec<ErgoBox>>();
37+
let input_ids = inputs
38+
.iter()
39+
.map(|input| UnsignedInput::new(input.box_id(), ContextExtension::empty()))
40+
.collect();
41+
let unsigned_tx = UnsignedTransaction::new_from_vec(
42+
input_ids,
43+
vec![],
44+
vec![
45+
ErgoBoxCandidateBuilder::new(BoxValue::SAFE_USER_MIN, true_tree.clone(), 1000)
46+
.build()
47+
.unwrap(),
48+
],
49+
)
50+
.unwrap();
51+
group.bench_with_input(
52+
BenchmarkId::from_parameter(format!("{range:4}")),
53+
&unsigned_tx,
54+
|b, tx| {
55+
b.iter_batched(
56+
|| (tx.clone(), inputs.clone(), vec![]),
57+
|(tx, inputs, data_inputs)| {
58+
TransactionContext::new(tx, inputs, data_inputs).unwrap()
59+
},
60+
BatchSize::SmallInput,
61+
)
62+
},
63+
);
64+
}
65+
group.finish();
66+
}
67+
68+
pub fn bench_tx_sign_wallet(c: &mut Criterion) {
69+
let mut sign_group = c.benchmark_group("sign ProveDlog inputs");
70+
sign_group
71+
.sample_size(10)
72+
.sampling_mode(SamplingMode::Flat)
73+
.warm_up_time(std::time::Duration::from_millis(50));
74+
75+
const MAX_INPUTS: usize = 100;
76+
let secrets = vec![SecretKey::random_dlog(); MAX_INPUTS];
77+
let inputs = (0..MAX_INPUTS)
78+
.map(|i| {
79+
ErgoBox::from_box_candidate(
80+
&ErgoBoxCandidateBuilder::new(
81+
BoxValue::SAFE_USER_MIN,
82+
secrets[i].get_address_from_public_image().script().unwrap(),
83+
1000,
84+
)
85+
.build()
86+
.unwrap(),
87+
TxId::zero(),
88+
i as u16,
89+
)
90+
.unwrap()
91+
})
92+
.collect::<Vec<ErgoBox>>();
93+
let wallet = Wallet::from_secrets(secrets);
94+
95+
for range in (1..=MAX_INPUTS).step_by(20) {
96+
let input_ids = inputs
97+
.iter()
98+
.take(range)
99+
.map(|input| UnsignedInput::new(input.box_id(), ContextExtension::empty()))
100+
.collect();
101+
let unsigned_tx = UnsignedTransaction::new_from_vec(
102+
input_ids,
103+
vec![],
104+
vec![ErgoBoxCandidateBuilder::new(
105+
BoxValue::SAFE_USER_MIN,
106+
ErgoTree::new(
107+
ErgoTreeHeader::new(0).unwrap(),
108+
&Constant::from(true).into(),
109+
)
110+
.unwrap(),
111+
1000,
112+
)
113+
.build()
114+
.unwrap()],
115+
)
116+
.unwrap();
117+
let tx_context =
118+
TransactionContext::new(unsigned_tx, inputs[0..range].to_owned(), vec![]).unwrap();
119+
sign_group.bench_with_input(
120+
BenchmarkId::from_parameter(format!("{range:4}")),
121+
&tx_context,
122+
|b, tx_context| {
123+
b.iter_batched(
124+
|| (tx_context.clone(), force_any_val()),
125+
|(tx_context, state_context)| {
126+
wallet
127+
.sign_transaction(tx_context, &state_context, None)
128+
.unwrap()
129+
},
130+
BatchSize::SmallInput,
131+
)
132+
},
133+
);
134+
}
135+
sign_group.finish();
136+
}
137+
138+
criterion_group!(benches, bench_tx_context, bench_tx_sign_wallet);
139+
criterion_main!(benches);

ergo-lib/src/chain/ergo_box/box_builder.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use alloc::string::String;
44
use alloc::string::ToString;
55
use alloc::vec::Vec;
6-
use core::convert::{TryFrom, TryInto};
6+
use core::convert::TryFrom;
77
use hashbrown::HashMap;
88

99
use ergotree_ir::chain::address::AddressEncoderError;
@@ -28,7 +28,7 @@ pub enum ErgoBoxCandidateBuilderError {
2828
/// box value that caused this error
2929
error_value: BoxValue,
3030
/// minimum box value for that box size
31-
min_box_value: BoxValue,
31+
min_box_value: i64,
3232
/// box size in bytes
3333
box_size_bytes: usize,
3434
},
@@ -259,10 +259,8 @@ impl ErgoBoxCandidateBuilder {
259259

260260
// Won't be overflowing an i64, so unwrap is safe.
261261
#[allow(clippy::unwrap_used)]
262-
let min_box_value: BoxValue = (box_size_bytes as i64 * self.min_value_per_byte as i64)
263-
.try_into()
264-
.unwrap();
265-
if self.value >= min_box_value {
262+
let min_box_value: i64 = box_size_bytes as i64 * self.min_value_per_byte as i64;
263+
if self.value.as_i64() >= min_box_value {
266264
Ok(b)
267265
} else {
268266
Err(ErgoBoxCandidateBuilderError::BoxValueTooLow {

ergotree-interpreter/Cargo.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ gf2_192 = { version = "^0.28.0", path = "../gf2_192" }
3939
miette = { workspace = true, optional = true }
4040
hashbrown = { workspace = true }
4141
core2 = { workspace = true }
42+
sigma-test-util = { workspace = true, optional = true }
4243
[features]
4344
json = [
4445
"serde",
@@ -57,6 +58,7 @@ arbitrary = [
5758
"ergotree-ir/arbitrary",
5859
"ergo-chain-types/arbitrary",
5960
"gf2_192/arbitrary",
61+
"sigma-test-util",
6062
]
6163

6264
[dev-dependencies]
@@ -65,3 +67,9 @@ ergoscript-compiler = { workspace = true }
6567
proptest = { workspace = true }
6668
sigma-test-util = { workspace = true }
6769
expect-test = { workspace = true }
70+
criterion = { workspace = true }
71+
72+
[[bench]]
73+
name = "eval_benches"
74+
harness = false
75+
required-features = ["arbitrary"]

0 commit comments

Comments
 (0)