Skip to content

Commit a9f44aa

Browse files
committed
Replace std's unmaintained bench with criterion
Rather than using the std benchmark framework (which isn't maintained and is unlikely to get any further maintenance), we swap for criterion, which at least gets us a variable number of test runs so our benchmarks don't take forever. We also fix the RGS benchmark to pass now that the file in use is stale compared to today's date.
1 parent 7eb7a84 commit a9f44aa

File tree

17 files changed

+180
-125
lines changed

17 files changed

+180
-125
lines changed

.github/workflows/build.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,12 @@ jobs:
141141
cd ..
142142
- name: Run benchmarks on Rust ${{ matrix.toolchain }}
143143
run: |
144-
RUSTC_BOOTSTRAP=1 cargo bench --features _bench_unstable
144+
cd bench
145+
RUSTFLAGS="--cfg=ldk_bench --cfg=require_route_graph_test" cargo bench
146+
- name: Run benchmarks with hashbrown on Rust ${{ matrix.toolchain }}
147+
run: |
148+
cd bench
149+
RUSTFLAGS="--cfg=ldk_bench --cfg=require_route_graph_test" cargo bench --features hashbrown
145150
146151
check_commits:
147152
runs-on: ubuntu-latest

Cargo.toml

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ exclude = [
1414
"lightning-custom-message",
1515
"lightning-transaction-sync",
1616
"no-std-check",
17+
"bench",
1718
]
1819

1920
# Our tests do actual crypto and lots of work, the tradeoff for -O2 is well
@@ -35,8 +36,3 @@ lto = "off"
3536
opt-level = 3
3637
lto = true
3738
panic = "abort"
38-
39-
[profile.bench]
40-
opt-level = 3
41-
codegen-units = 1
42-
lto = true

bench/Cargo.toml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
[package]
2+
name = "lightning-bench"
3+
version = "0.0.1"
4+
authors = ["Matt Corallo"]
5+
edition = "2018"
6+
7+
[[bench]]
8+
name = "bench"
9+
harness = false
10+
11+
[features]
12+
hashbrown = ["lightning/hashbrown"]
13+
14+
[dependencies]
15+
lightning = { path = "../lightning", features = ["_test_utils", "criterion"] }
16+
lightning-persister = { path = "../lightning-persister", features = ["criterion"] }
17+
lightning-rapid-gossip-sync = { path = "../lightning-rapid-gossip-sync", features = ["criterion"] }
18+
criterion = { version = "0.4", default-features = false }
19+
20+
[profile.release]
21+
opt-level = 3
22+
codegen-units = 1
23+
lto = true
24+
panic = "abort"
25+
debug = true

bench/benches/bench.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
extern crate lightning;
2+
extern crate lightning_persister;
3+
4+
extern crate criterion;
5+
6+
use criterion::{criterion_group, criterion_main};
7+
8+
criterion_group!(benches,
9+
// Note that benches run in the order given here. Thus, they're sorted according to how likely
10+
// developers are to be working on the specific code listed, then by runtime.
11+
lightning::routing::router::benches::generate_routes_with_zero_penalty_scorer,
12+
lightning::routing::router::benches::generate_mpp_routes_with_zero_penalty_scorer,
13+
lightning::routing::router::benches::generate_routes_with_probabilistic_scorer,
14+
lightning::routing::router::benches::generate_mpp_routes_with_probabilistic_scorer,
15+
lightning::routing::router::benches::generate_large_mpp_routes_with_probabilistic_scorer,
16+
lightning::chain::keysinterface::benches::bench_get_secure_random_bytes,
17+
lightning::ln::channelmanager::bench::bench_sends,
18+
lightning_persister::bench::bench_sends,
19+
lightning_rapid_gossip_sync::bench::bench_reading_full_graph_from_file,
20+
lightning::routing::gossip::benches::read_network_graph,
21+
lightning::routing::gossip::benches::write_network_graph);
22+
criterion_main!(benches);

lightning-persister/Cargo.toml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,13 @@ edition = "2018"
1313
all-features = true
1414
rustdoc-args = ["--cfg", "docsrs"]
1515

16-
[features]
17-
_bench_unstable = ["lightning/_bench_unstable"]
18-
1916
[dependencies]
2017
bitcoin = "0.29.0"
2118
lightning = { version = "0.0.115", path = "../lightning" }
2219
libc = "0.2"
2320

21+
criterion = { version = "0.4", optional = true, default-features = false }
22+
2423
[target.'cfg(windows)'.dependencies]
2524
winapi = { version = "0.3", features = ["winbase"] }
2625

lightning-persister/src/lib.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@
88

99
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
1010

11-
#![cfg_attr(all(test, feature = "_bench_unstable"), feature(test))]
12-
#[cfg(all(test, feature = "_bench_unstable"))] extern crate test;
11+
#[cfg(ldk_bench)] extern crate criterion;
1312

1413
mod util;
1514

@@ -91,13 +90,13 @@ impl FilesystemPersister {
9190
continue;
9291
}
9392

94-
let txid = Txid::from_hex(filename.split_at(64).0)
93+
let txid: Txid = Txid::from_hex(filename.split_at(64).0)
9594
.map_err(|_| std::io::Error::new(
9695
std::io::ErrorKind::InvalidData,
9796
"Invalid tx ID in filename",
9897
))?;
9998

100-
let index = filename.split_at(65).1.parse()
99+
let index: u16 = filename.split_at(65).1.parse()
101100
.map_err(|_| std::io::Error::new(
102101
std::io::ErrorKind::InvalidData,
103102
"Invalid tx index in filename",
@@ -338,14 +337,16 @@ mod tests {
338337
}
339338
}
340339

341-
#[cfg(all(test, feature = "_bench_unstable"))]
340+
#[cfg(ldk_bench)]
341+
/// Benches
342342
pub mod bench {
343-
use test::Bencher;
343+
use criterion::Criterion;
344344

345-
#[bench]
346-
fn bench_sends(bench: &mut Bencher) {
345+
/// Bench!
346+
pub fn bench_sends(bench: &mut Criterion) {
347347
let persister_a = super::FilesystemPersister::new("bench_filesystem_persister_a".to_string());
348348
let persister_b = super::FilesystemPersister::new("bench_filesystem_persister_b".to_string());
349-
lightning::ln::channelmanager::bench::bench_two_sends(bench, persister_a, persister_b);
349+
lightning::ln::channelmanager::bench::bench_two_sends(
350+
bench, "bench_filesystem_persisted_sends", persister_a, persister_b);
350351
}
351352
}

lightning-rapid-gossip-sync/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@ Utility to process gossip routing data from Rapid Gossip Sync Server.
1313
default = ["std"]
1414
no-std = ["lightning/no-std"]
1515
std = ["lightning/std"]
16-
_bench_unstable = []
1716

1817
[dependencies]
1918
lightning = { version = "0.0.115", path = "../lightning", default-features = false }
2019
bitcoin = { version = "0.29.0", default-features = false }
2120

21+
criterion = { version = "0.4", optional = true, default-features = false }
22+
2223
[dev-dependencies]
2324
lightning = { version = "0.0.115", path = "../lightning", features = ["_test_utils"] }

lightning-rapid-gossip-sync/src/lib.rs

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,7 @@
6464
6565
#![cfg_attr(all(not(feature = "std"), not(test)), no_std)]
6666

67-
// Allow and import test features for benching
68-
#![cfg_attr(all(test, feature = "_bench_unstable"), feature(test))]
69-
#[cfg(all(test, feature = "_bench_unstable"))]
70-
extern crate test;
67+
#[cfg(ldk_bench)] extern crate criterion;
7168

7269
#[cfg(not(feature = "std"))]
7370
extern crate alloc;
@@ -287,36 +284,42 @@ mod tests {
287284
}
288285
}
289286

290-
#[cfg(all(test, feature = "_bench_unstable"))]
287+
#[cfg(ldk_bench)]
288+
/// Benches
291289
pub mod bench {
292-
use test::Bencher;
293-
294290
use bitcoin::Network;
295291

296-
use lightning::ln::msgs::DecodeError;
292+
use criterion::Criterion;
293+
294+
use std::fs;
295+
297296
use lightning::routing::gossip::NetworkGraph;
298297
use lightning::util::test_utils::TestLogger;
299298

300299
use crate::RapidGossipSync;
301300

302-
#[bench]
303-
fn bench_reading_full_graph_from_file(b: &mut Bencher) {
301+
/// Bench!
302+
pub fn bench_reading_full_graph_from_file(b: &mut Criterion) {
304303
let logger = TestLogger::new();
305-
b.iter(|| {
304+
b.bench_function("read_full_graph_from_rgs", |b| b.iter(|| {
306305
let network_graph = NetworkGraph::new(Network::Bitcoin, &logger);
307306
let rapid_sync = RapidGossipSync::new(&network_graph, &logger);
308-
let sync_result = rapid_sync.sync_network_graph_with_file_path("./res/full_graph.lngossip");
309-
if let Err(crate::error::GraphSyncError::DecodeError(DecodeError::Io(io_error))) = &sync_result {
310-
let error_string = format!("Input file lightning-rapid-gossip-sync/res/full_graph.lngossip is missing! Download it from https://bitcoin.ninja/ldk-compressed_graph-bc08df7542-2022-05-05.bin\n\n{:?}", io_error);
311-
#[cfg(not(require_route_graph_test))]
312-
{
313-
println!("{}", error_string);
314-
return;
315-
}
316-
#[cfg(require_route_graph_test)]
317-
panic!("{}", error_string);
318-
}
319-
assert!(sync_result.is_ok())
320-
});
307+
let mut file = match fs::read("../lightning-rapid-gossip-sync/res/full_graph.lngossip") {
308+
Ok(f) => f,
309+
Err(io_error) => {
310+
let error_string = format!(
311+
"Input file lightning-rapid-gossip-sync/res/full_graph.lngossip is missing! Download it from https://bitcoin.ninja/ldk-compressed_graph-bc08df7542-2022-05-05.bin\n\n{:?}",
312+
io_error);
313+
#[cfg(not(require_route_graph_test))]
314+
{
315+
println!("{}", error_string);
316+
return;
317+
}
318+
#[cfg(require_route_graph_test)]
319+
panic!("{}", error_string);
320+
},
321+
};
322+
rapid_sync.update_network_graph_no_std(&mut file, None).unwrap();
323+
}));
321324
}
322325
}

lightning/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ max_level_trace = []
2828
# Allow signing of local transactions that may have been revoked or will be revoked, for functional testing (e.g. justice tx handling).
2929
# This is unsafe to use in production because it may result in the counterparty publishing taking our funds.
3030
unsafe_revoked_tx_signing = []
31-
_bench_unstable = []
3231
# Override signing to not include randomness when generating signatures for test vectors.
3332
_test_vectors = []
3433

@@ -50,6 +49,8 @@ backtrace = { version = "0.3", optional = true }
5049

5150
core2 = { version = "0.3.0", optional = true, default-features = false }
5251

52+
criterion = { version = "0.4", optional = true, default-features = false }
53+
5354
[dev-dependencies]
5455
hex = "0.4"
5556
regex = "1.5.6"

lightning/src/chain/keysinterface.rs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1523,8 +1523,8 @@ pub fn dyn_sign() {
15231523
let _signer: Box<dyn EcdsaChannelSigner>;
15241524
}
15251525

1526-
#[cfg(all(test, feature = "_bench_unstable", not(feature = "no-std")))]
1527-
mod benches {
1526+
#[cfg(ldk_bench)]
1527+
pub mod benches {
15281528
use std::sync::{Arc, mpsc};
15291529
use std::sync::mpsc::TryRecvError;
15301530
use std::thread;
@@ -1533,10 +1533,9 @@ mod benches {
15331533
use bitcoin::Network;
15341534
use crate::chain::keysinterface::{EntropySource, KeysManager};
15351535

1536-
use test::Bencher;
1536+
use criterion::Criterion;
15371537

1538-
#[bench]
1539-
fn bench_get_secure_random_bytes(bench: &mut Bencher) {
1538+
pub fn bench_get_secure_random_bytes(bench: &mut Criterion) {
15401539
let seed = [0u8; 32];
15411540
let now = Duration::from_secs(genesis_block(Network::Testnet).header.time as u64);
15421541
let keys_manager = Arc::new(KeysManager::new(&seed, now.as_secs(), now.subsec_micros()));
@@ -1562,11 +1561,8 @@ mod benches {
15621561
stops.push(stop_sender);
15631562
}
15641563

1565-
bench.iter(|| {
1566-
for _ in 1..100 {
1567-
keys_manager.get_secure_random_bytes();
1568-
}
1569-
});
1564+
bench.bench_function("get_secure_random_bytes", |b| b.iter(||
1565+
keys_manager.get_secure_random_bytes()));
15701566

15711567
for stop in stops {
15721568
let _ = stop.send(());
@@ -1575,5 +1571,4 @@ mod benches {
15751571
handle.join().unwrap();
15761572
}
15771573
}
1578-
15791574
}

lightning/src/lib.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,6 @@
5454

5555
#![cfg_attr(all(not(feature = "std"), not(test)), no_std)]
5656

57-
#![cfg_attr(all(any(test, feature = "_test_utils"), feature = "_bench_unstable"), feature(test))]
58-
#[cfg(all(any(test, feature = "_test_utils"), feature = "_bench_unstable"))] extern crate test;
59-
6057
#[cfg(not(any(feature = "std", feature = "no-std")))]
6158
compile_error!("at least one of the `std` or `no-std` features must be enabled");
6259

@@ -74,6 +71,8 @@ extern crate core;
7471

7572
#[cfg(not(feature = "std"))] extern crate core2;
7673

74+
#[cfg(ldk_bench)] extern crate criterion;
75+
7776
#[macro_use]
7877
pub mod util;
7978
pub mod chain;
@@ -176,7 +175,7 @@ mod prelude {
176175
pub use alloc::string::ToString;
177176
}
178177

179-
#[cfg(all(not(feature = "_bench_unstable"), feature = "backtrace", feature = "std", test))]
178+
#[cfg(all(not(ldk_bench), feature = "backtrace", feature = "std", test))]
180179
extern crate backtrace;
181180

182181
mod sync;

lightning/src/ln/channelmanager.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9005,7 +9005,7 @@ mod tests {
90059005
}
90069006
}
90079007

9008-
#[cfg(all(any(test, feature = "_test_utils"), feature = "_bench_unstable"))]
9008+
#[cfg(ldk_bench)]
90099009
pub mod bench {
90109010
use crate::chain::Listen;
90119011
use crate::chain::chainmonitor::{ChainMonitor, Persist};
@@ -9025,7 +9025,7 @@ pub mod bench {
90259025

90269026
use crate::sync::{Arc, Mutex};
90279027

9028-
use test::Bencher;
9028+
use criterion::Criterion;
90299029

90309030
type Manager<'a, P> = ChannelManager<
90319031
&'a ChainMonitor<InMemorySigner, &'a test_utils::TestChainSource,
@@ -9046,13 +9046,11 @@ pub mod bench {
90469046
fn chain_monitor(&self) -> Option<&test_utils::TestChainMonitor> { None }
90479047
}
90489048

9049-
#[cfg(test)]
9050-
#[bench]
9051-
fn bench_sends(bench: &mut Bencher) {
9052-
bench_two_sends(bench, test_utils::TestPersister::new(), test_utils::TestPersister::new());
9049+
pub fn bench_sends(bench: &mut Criterion) {
9050+
bench_two_sends(bench, "bench_sends", test_utils::TestPersister::new(), test_utils::TestPersister::new());
90539051
}
90549052

9055-
pub fn bench_two_sends<P: Persist<InMemorySigner>>(bench: &mut Bencher, persister_a: P, persister_b: P) {
9053+
pub fn bench_two_sends<P: Persist<InMemorySigner>>(bench: &mut Criterion, bench_name: &str, persister_a: P, persister_b: P) {
90569054
// Do a simple benchmark of sending a payment back and forth between two nodes.
90579055
// Note that this is unrealistic as each payment send will require at least two fsync
90589056
// calls per node.
@@ -9208,9 +9206,9 @@ pub mod bench {
92089206
}
92099207
}
92109208

9211-
bench.iter(|| {
9209+
bench.bench_function(bench_name, |b| b.iter(|| {
92129210
send_payment!(node_a, node_b);
92139211
send_payment!(node_b, node_a);
9214-
});
9212+
}));
92159213
}
92169214
}

0 commit comments

Comments
 (0)