-
Notifications
You must be signed in to change notification settings - Fork 188
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
179 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
#![feature(test)] | ||
#![cfg(feature = "rand")] | ||
|
||
extern crate num_bigint; | ||
extern crate num_traits; | ||
extern crate rand; | ||
extern crate test; | ||
|
||
use num_bigint::{BigUint, RandBigInt}; | ||
use num_traits::Pow; | ||
use rand::{SeedableRng, StdRng}; | ||
use test::Bencher; | ||
|
||
// The `big64` cases demonstrate the speed of cases where the value | ||
// can be converted to a `u64` primitive for faster calculation. | ||
// | ||
// The `big1k` cases demonstrate those that can convert to `f64` for | ||
// a better initial guess of the actual value. | ||
// | ||
// The `big2k` and `big4k` cases are too big for `f64`, and use a simpler guess. | ||
|
||
fn get_rng() -> StdRng { | ||
let mut seed = [0; 32]; | ||
for i in 1..32 { | ||
seed[usize::from(i)] = i; | ||
} | ||
SeedableRng::from_seed(seed) | ||
} | ||
|
||
fn check(x: &BigUint, n: u32) { | ||
let root = x.nth_root(n); | ||
if n == 2 { | ||
assert_eq!(root, x.sqrt()) | ||
} else if n == 3 { | ||
assert_eq!(root, x.cbrt()) | ||
} | ||
|
||
let lo = root.pow(n); | ||
assert!(lo <= *x); | ||
assert_eq!(lo.nth_root(n), root); | ||
assert_eq!((&lo - 1u32).nth_root(n), &root - 1u32); | ||
|
||
let hi = (&root + 1u32).pow(n); | ||
assert!(hi > *x); | ||
assert_eq!(hi.nth_root(n), &root + 1u32); | ||
assert_eq!((&hi - 1u32).nth_root(n), root); | ||
} | ||
|
||
fn bench_sqrt(b: &mut Bencher, bits: usize) { | ||
let x = get_rng().gen_biguint(bits); | ||
eprintln!("bench_sqrt({})", x); | ||
|
||
check(&x, 2); | ||
b.iter(|| x.sqrt()); | ||
} | ||
|
||
#[bench] | ||
fn big64_sqrt(b: &mut Bencher) { | ||
bench_sqrt(b, 64); | ||
} | ||
|
||
#[bench] | ||
fn big1k_sqrt(b: &mut Bencher) { | ||
bench_sqrt(b, 1024); | ||
} | ||
|
||
#[bench] | ||
fn big2k_sqrt(b: &mut Bencher) { | ||
bench_sqrt(b, 2048); | ||
} | ||
|
||
#[bench] | ||
fn big4k_sqrt(b: &mut Bencher) { | ||
bench_sqrt(b, 4096); | ||
} | ||
|
||
fn bench_cbrt(b: &mut Bencher, bits: usize) { | ||
let x = get_rng().gen_biguint(bits); | ||
eprintln!("bench_cbrt({})", x); | ||
|
||
check(&x, 3); | ||
b.iter(|| x.cbrt()); | ||
} | ||
|
||
#[bench] | ||
fn big64_cbrt(b: &mut Bencher) { | ||
bench_cbrt(b, 64); | ||
} | ||
|
||
#[bench] | ||
fn big1k_cbrt(b: &mut Bencher) { | ||
bench_cbrt(b, 1024); | ||
} | ||
|
||
#[bench] | ||
fn big2k_cbrt(b: &mut Bencher) { | ||
bench_cbrt(b, 2048); | ||
} | ||
|
||
#[bench] | ||
fn big4k_cbrt(b: &mut Bencher) { | ||
bench_cbrt(b, 4096); | ||
} | ||
|
||
fn bench_nth_root(b: &mut Bencher, bits: usize, n: u32) { | ||
let x = get_rng().gen_biguint(bits); | ||
eprintln!("bench_{}th_root({})", n, x); | ||
|
||
check(&x, n); | ||
b.iter(|| x.nth_root(n)); | ||
} | ||
|
||
#[bench] | ||
fn big64_nth_10(b: &mut Bencher) { | ||
bench_nth_root(b, 64, 10); | ||
} | ||
|
||
#[bench] | ||
fn big1k_nth_10(b: &mut Bencher) { | ||
bench_nth_root(b, 1024, 10); | ||
} | ||
|
||
#[bench] | ||
fn big1k_nth_100(b: &mut Bencher) { | ||
bench_nth_root(b, 1024, 100); | ||
} | ||
|
||
#[bench] | ||
fn big1k_nth_1000(b: &mut Bencher) { | ||
bench_nth_root(b, 1024, 1000); | ||
} | ||
|
||
#[bench] | ||
fn big1k_nth_10000(b: &mut Bencher) { | ||
bench_nth_root(b, 1024, 10000); | ||
} | ||
|
||
#[bench] | ||
fn big2k_nth_10(b: &mut Bencher) { | ||
bench_nth_root(b, 2048, 10); | ||
} | ||
|
||
#[bench] | ||
fn big2k_nth_100(b: &mut Bencher) { | ||
bench_nth_root(b, 2048, 100); | ||
} | ||
|
||
#[bench] | ||
fn big2k_nth_1000(b: &mut Bencher) { | ||
bench_nth_root(b, 2048, 1000); | ||
} | ||
|
||
#[bench] | ||
fn big2k_nth_10000(b: &mut Bencher) { | ||
bench_nth_root(b, 2048, 10000); | ||
} | ||
|
||
#[bench] | ||
fn big4k_nth_10(b: &mut Bencher) { | ||
bench_nth_root(b, 4096, 10); | ||
} | ||
|
||
#[bench] | ||
fn big4k_nth_100(b: &mut Bencher) { | ||
bench_nth_root(b, 4096, 100); | ||
} | ||
|
||
#[bench] | ||
fn big4k_nth_1000(b: &mut Bencher) { | ||
bench_nth_root(b, 4096, 1000); | ||
} | ||
|
||
#[bench] | ||
fn big4k_nth_10000(b: &mut Bencher) { | ||
bench_nth_root(b, 4096, 10000); | ||
} |