Skip to content

Commit 692a12c

Browse files
committed
Add benchmarks
Add benchmarks for parsing and encoding bitcoin addresses. Also add two unit tests that parse the same address string used in the benchmarks. Specifically benchmark: - decoding an address - encoding an address with allocation - encoding an address without allocation Do so for both Bitcoin bech32 addresses and Bitcoin bech32m addresses.
1 parent b70663f commit 692a12c

File tree

2 files changed

+105
-0
lines changed

2 files changed

+105
-0
lines changed

README.md

+5
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,8 @@ Bitcoin-specific address encoding is handled by the `bitcoin-bech32` crate.
1515

1616
The minimum supported Rust version with the standard library is **1.41.1**.
1717

18+
19+
## Benchmarks
20+
21+
We use a custom Rust compiler configuration conditional to guard the bench mark code. To run the
22+
bench marks use: `RUSTFLAGS='--cfg=bench' cargo +nightly bench`.

src/lib.rs

+100
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ assert_eq!(variant, Variant::Bech32);
4646
)]
4747
//!
4848
49+
// Experimental features we need.
50+
#![cfg_attr(bench, feature(test))]
4951
// Allow trait objects without dyn on nightly and make 1.22 ignore the unknown lint
5052
#![allow(unknown_lints)]
5153
#![allow(bare_trait_objects)]
@@ -57,6 +59,9 @@ assert_eq!(variant, Variant::Bech32);
5759
#![cfg_attr(feature = "strict", deny(warnings))]
5860
#![cfg_attr(all(not(feature = "std"), not(test)), no_std)]
5961

62+
#[cfg(bench)]
63+
extern crate test;
64+
6065
#[cfg(feature = "alloc")]
6166
extern crate alloc;
6267

@@ -1393,4 +1398,99 @@ mod tests {
13931398
assert_eq!(&res, [0x00, 0x01, 0x02].as_ref());
13941399
assert_eq!(variant, Variant::Bech32);
13951400
}
1401+
1402+
#[test]
1403+
#[cfg(feature = "alloc")]
1404+
fn decode_bitcoin_bech32_address() {
1405+
let addr = "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq";
1406+
let (hrp, _data, variant) = crate::decode(addr).expect("address is well formed");
1407+
assert_eq!(hrp, "bc");
1408+
assert_eq!(variant, Variant::Bech32)
1409+
}
1410+
1411+
#[test]
1412+
#[cfg(feature = "alloc")]
1413+
fn decode_bitcoin_bech32m_address() {
1414+
let addr = "bc1p5d7rjq7g6rdk2yhzks9smlaqtedr4dekq08ge8ztwac72sfr9rusxg3297";
1415+
let (hrp, _data, variant) = crate::decode(addr).expect("address is well formed");
1416+
assert_eq!(hrp, "bc");
1417+
assert_eq!(variant, Variant::Bech32m)
1418+
}
1419+
}
1420+
1421+
#[cfg(bench)]
1422+
mod benches {
1423+
use test::{black_box, Bencher};
1424+
1425+
#[bench]
1426+
fn bech32_parse_address(bh: &mut Bencher) {
1427+
let addr = black_box("bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq");
1428+
1429+
bh.iter(|| {
1430+
let tuple = crate::decode(&addr).expect("address is well formed");
1431+
black_box(&tuple);
1432+
})
1433+
}
1434+
1435+
#[bench]
1436+
fn bech32m_parse_address(bh: &mut Bencher) {
1437+
let addr = black_box("bc1p5d7rjq7g6rdk2yhzks9smlaqtedr4dekq08ge8ztwac72sfr9rusxg3297");
1438+
1439+
bh.iter(|| {
1440+
let tuple = crate::decode(&addr).expect("address is well formed");
1441+
black_box(&tuple);
1442+
})
1443+
}
1444+
1445+
// Encode with allocation.
1446+
#[bench]
1447+
fn encode_bech32_address(bh: &mut Bencher) {
1448+
let addr = "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq";
1449+
let (hrp, data, variant) = crate::decode(&addr).expect("address is well formed");
1450+
1451+
bh.iter(|| {
1452+
let s = crate::encode(&hrp, &data, variant).expect("failed to encode");
1453+
black_box(&s);
1454+
});
1455+
}
1456+
1457+
// Encode without allocation.
1458+
#[bench]
1459+
fn encode_to_fmt_bech32_address(bh: &mut Bencher) {
1460+
let addr = "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq";
1461+
let (hrp, data, variant) = crate::decode(&addr).expect("address is well formed");
1462+
let mut buf = String::with_capacity(64);
1463+
1464+
bh.iter(|| {
1465+
let res =
1466+
crate::encode_to_fmt(&mut buf, &hrp, &data, variant).expect("failed to encode");
1467+
black_box(&res);
1468+
});
1469+
}
1470+
1471+
// Encode with allocation.
1472+
#[bench]
1473+
fn encode_bech32m_address(bh: &mut Bencher) {
1474+
let addr = "bc1p5d7rjq7g6rdk2yhzks9smlaqtedr4dekq08ge8ztwac72sfr9rusxg3297";
1475+
let (hrp, data, variant) = crate::decode(&addr).expect("address is well formed");
1476+
1477+
bh.iter(|| {
1478+
let s = crate::encode(&hrp, &data, variant).expect("failed to encode");
1479+
black_box(&s);
1480+
});
1481+
}
1482+
1483+
// Encode without allocation.
1484+
#[bench]
1485+
fn encode_to_fmt_bech32m_address(bh: &mut Bencher) {
1486+
let addr = "bc1p5d7rjq7g6rdk2yhzks9smlaqtedr4dekq08ge8ztwac72sfr9rusxg3297";
1487+
let (hrp, data, variant) = crate::decode(&addr).expect("address is well formed");
1488+
let mut buf = String::with_capacity(64);
1489+
1490+
bh.iter(|| {
1491+
let res =
1492+
crate::encode_to_fmt(&mut buf, &hrp, &data, variant).expect("failed to encode");
1493+
black_box(&res);
1494+
});
1495+
}
13961496
}

0 commit comments

Comments
 (0)