Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
55 changes: 55 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion core/primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ rand = "0.7.2"
criterion = "0.2.11"

[[bench]]
name = "benches"
name = "bench"
harness = false

[lib]
Expand Down
6 changes: 5 additions & 1 deletion core/sr-arithmetic/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ substrate-debug-derive = { path = "../primitives/debug-derive", default-features
[dev-dependencies]
primitive-types = "0.6.0"
rand = "0.7.2"
criterion = "0.3"

[features]
bench = []
default = ["std"]
std = [
"codec/std",
Expand All @@ -26,3 +26,7 @@ std = [
"serde",
"substrate-debug-derive/std",
]

[[bench]]
name = "bench"
harness = false
80 changes: 80 additions & 0 deletions core/sr-arithmetic/benches/bench.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Copyright 2019 Parity Technologies (UK) Ltd.
// This file is part of Substrate.

// Substrate is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Substrate is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.

use criterion::{Criterion, Throughput, BenchmarkId, criterion_group, criterion_main};
use sr_arithmetic::biguint::{BigUint, Single};
use rand::Rng;

fn random_big_uint(size: usize) -> BigUint {
let mut rng = rand::thread_rng();
let digits: Vec<_> = (0..size).map(|_| rng.gen_range(0, Single::max_value())).collect();
BigUint::from_limbs(&digits)
}

fn bench_op<F: Fn(&BigUint, &BigUint)>(c: &mut Criterion, name: &str, op: F) {
let mut group = c.benchmark_group(name);

for size in [2, 4, 6, 8, 10].iter() {
group.throughput(Throughput::Elements(*size));
group.bench_with_input(BenchmarkId::from_parameter(size), size, |bencher, &size| {
let a = random_big_uint(size as usize);
let b = random_big_uint(size as usize);

bencher.iter(|| op(&a, &b));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm I just ran it and being amazed of why division is as fast as addition: we don't do division p / q if the size of q is equal to p. Need to be reworked. I'd leave it up to you regarding how to bake it out of criterion, but ideally, given p with size limbs, we should chose a secondary random number between [2, size-1] and build a number of that size and divide them.

});
}
}

fn bench_addition(c: &mut Criterion) {
bench_op(c, "addition", |a, b| {
let _ = a.clone().add(&b);
});
}

fn bench_subtraction(c: &mut Criterion) {
bench_op(c, "subtraction", |a, b| {
let _ = a.clone().sub(&b);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let _ = a.clone().sub(&b);
let _ = a.clone().sub(&b);

better to have let _ = .. consistently for all or none.

});
}

fn bench_multiplication(c: &mut Criterion) {
bench_op(c, "multiplication", |a, b| {
let _ = a.clone().mul(&b);
});
}

fn bench_division(c: &mut Criterion) {
let mut group = c.benchmark_group("division");

for size in [4, 6, 8, 10].iter() {
group.throughput(Throughput::Elements(*size));
group.bench_with_input(BenchmarkId::from_parameter(size), size, |bencher, &size| {
let a = random_big_uint(size as usize);
let b = random_big_uint(rand::thread_rng().gen_range(2, size as usize));

bencher.iter(|| {
let _ = a.clone().div(&b, true);
});
});
}
}

criterion_group!{
name = benches;
config = Criterion::default();
targets = bench_addition, bench_subtraction, bench_multiplication, bench_division
}
criterion_main!(benches);
80 changes: 0 additions & 80 deletions core/sr-arithmetic/src/biguint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -561,8 +561,6 @@ impl From<Double> for BigUint {
#[cfg(test)]
pub mod tests {
use super::*;
#[cfg(feature = "bench")]
use test::Bencher;

fn with_limbs(n: usize) -> BigUint {
BigUint { digits: vec![1; n] }
Expand Down Expand Up @@ -734,82 +732,4 @@ pub mod tests {
assert_eq!(b.clone().div_unit(7), BigUint::from(((B + 100) / 7) as Single));

}

#[cfg(feature = "bench")]
fn random_big_uint(size: usize) -> BigUint {
use rand::Rng;
let mut rng = rand::thread_rng();
let digits = (0..size).map(|_| rng.gen_range(0, Single::max_value())).collect();
BigUint { digits }
}

#[cfg(feature = "bench")]
#[bench]
fn bench_addition_2_digit(bencher: &mut Bencher) {
let a = random_big_uint(2);
let b = random_big_uint(2);
bencher.iter(|| {
let _ = a.clone().add(&b);
});
}

#[cfg(feature = "bench")]
#[bench]
fn bench_addition_4_digit(bencher: &mut Bencher) {
let a = random_big_uint(4);
let b = random_big_uint(4);
bencher.iter(|| {
let _ = a.clone().add(&b);
});
}

#[cfg(feature = "bench")]
#[bench]
fn bench_subtraction_2_digit(bencher: &mut Bencher) {
let a = random_big_uint(2);
let b = random_big_uint(2);
bencher.iter(|| {
let _ = a.clone().sub(&b);
});
}

#[cfg(feature = "bench")]
#[bench]
fn bench_subtraction_4_digit(bencher: &mut Bencher) {
let a = random_big_uint(4);
let b = random_big_uint(4);
bencher.iter(|| {
let _ = a.clone().sub(&b);
});
}

#[cfg(feature = "bench")]
#[bench]
fn bench_multiplication_2_digit(bencher: &mut Bencher) {
let a = random_big_uint(2);
let b = random_big_uint(2);
bencher.iter(|| {
let _ = a.clone().mul(&b);
});
}

#[cfg(feature = "bench")]
#[bench]
fn bench_multiplication_4_digit(bencher: &mut Bencher) {
let a = random_big_uint(4);
let b = random_big_uint(4);
bencher.iter(|| {
let _ = a.clone().mul(&b);
});
}

#[cfg(feature = "bench")]
#[bench]
fn bench_division_4_digit(bencher: &mut Bencher) {
let a = random_big_uint(4);
let b = random_big_uint(2);
bencher.iter(|| {
let _ = a.clone().div(&b, true);
});
}
}
4 changes: 0 additions & 4 deletions core/sr-arithmetic/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,6 @@

#![cfg_attr(not(feature = "std"), no_std)]

// to allow benchmarking
#![cfg_attr(feature = "bench", feature(test))]
#[cfg(feature = "bench")] extern crate test;

/// Copied from `sr-primitives` and documented there.
#[cfg(test)]
macro_rules! assert_eq_error_rate {
Expand Down