Skip to content

Add benchmarks #97

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ jobs:
env:
DO_DOCSRS: true
DO_FMT: true
DO_BENCH: true
run: ./contrib/test.sh

MSRV:
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,9 @@ git config --local core.hooksPath githooks/
```

Alternatively add symlinks in your `.git/hooks` directory to any of the githooks we provide.


## Benchmarks

We use a custom Rust compiler configuration conditional to guard the benchmark code. To run the
benchmarks use: `RUSTFLAGS='--cfg=bench' cargo +nightly bench`.
12 changes: 12 additions & 0 deletions contrib/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,16 @@ if [ "${DO_DOCS-false}" = true ]; then
RUSTDOCFLAGS="-D warnings" cargo +stable doc --all-features
fi

# Bench if told to.
if [ "${DO_BENCH-false}" = true ]
then
# Technically we could use beta too but we only run this in CI using nightly.
if [ "$NIGHTLY" = false ]; then
echo "DO_BENCH requires a nightly toolchain (consider using RUSTUP_TOOLCHAIN)"
exit 1
fi

RUSTFLAGS='--cfg=bench' cargo bench
fi

exit 0
99 changes: 99 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,14 @@ assert_eq!(variant, Variant::Bech32);

#![cfg_attr(all(not(feature = "std"), not(test)), no_std)]
// Experimental features we need.
#![cfg_attr(bench, feature(test))]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
// Coding conventions
#![deny(missing_docs)]

#[cfg(bench)]
extern crate test;

#[cfg(feature = "alloc")]
extern crate alloc;

Expand Down Expand Up @@ -1399,4 +1403,99 @@ mod tests {
assert_eq!(&res, [0x00, 0x01, 0x02].as_ref());
assert_eq!(variant, Variant::Bech32);
}

#[test]
#[cfg(feature = "alloc")]
fn decode_bitcoin_bech32_address() {
let addr = "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq";
let (hrp, _data, variant) = crate::decode(addr).expect("address is well formed");
assert_eq!(hrp, "bc");
assert_eq!(variant, Variant::Bech32)
}

#[test]
#[cfg(feature = "alloc")]
fn decode_bitcoin_bech32m_address() {
let addr = "bc1p5d7rjq7g6rdk2yhzks9smlaqtedr4dekq08ge8ztwac72sfr9rusxg3297";
let (hrp, _data, variant) = crate::decode(addr).expect("address is well formed");
assert_eq!(hrp, "bc");
assert_eq!(variant, Variant::Bech32m)
}
}

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

#[bench]
fn bech32_parse_address(bh: &mut Bencher) {
let addr = black_box("bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq");

bh.iter(|| {
let tuple = crate::decode(&addr).expect("address is well formed");
black_box(&tuple);
})
}

#[bench]
fn bech32m_parse_address(bh: &mut Bencher) {
let addr = black_box("bc1p5d7rjq7g6rdk2yhzks9smlaqtedr4dekq08ge8ztwac72sfr9rusxg3297");

bh.iter(|| {
let tuple = crate::decode(&addr).expect("address is well formed");
black_box(&tuple);
})
}

// Encode with allocation.
#[bench]
fn encode_bech32_address(bh: &mut Bencher) {
let addr = "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq";
let (hrp, data, variant) = crate::decode(&addr).expect("address is well formed");

bh.iter(|| {
let s = crate::encode(&hrp, &data, variant).expect("failed to encode");
black_box(&s);
});
}

// Encode without allocation.
#[bench]
fn encode_to_fmt_bech32_address(bh: &mut Bencher) {
let addr = "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq";
let (hrp, data, variant) = crate::decode(&addr).expect("address is well formed");
let mut buf = String::with_capacity(64);

bh.iter(|| {
let res =
crate::encode_to_fmt(&mut buf, &hrp, &data, variant).expect("failed to encode");
black_box(&res);
});
}

// Encode with allocation.
#[bench]
fn encode_bech32m_address(bh: &mut Bencher) {
let addr = "bc1p5d7rjq7g6rdk2yhzks9smlaqtedr4dekq08ge8ztwac72sfr9rusxg3297";
let (hrp, data, variant) = crate::decode(&addr).expect("address is well formed");

bh.iter(|| {
let s = crate::encode(&hrp, &data, variant).expect("failed to encode");
black_box(&s);
});
}

// Encode without allocation.
#[bench]
fn encode_to_fmt_bech32m_address(bh: &mut Bencher) {
let addr = "bc1p5d7rjq7g6rdk2yhzks9smlaqtedr4dekq08ge8ztwac72sfr9rusxg3297";
let (hrp, data, variant) = crate::decode(&addr).expect("address is well formed");
let mut buf = String::with_capacity(64);

bh.iter(|| {
let res =
crate::encode_to_fmt(&mut buf, &hrp, &data, variant).expect("failed to encode");
black_box(&res);
});
}
}