|  | #![feature(test)] | 
|  | #![cfg(feature = "rand")] | 
|  |  | 
|  | extern crate test; | 
|  |  | 
|  | use num_bigint::{BigUint, RandBigInt}; | 
|  | use test::Bencher; | 
|  |  | 
|  | mod rng; | 
|  | use rng::get_rng; | 
|  |  | 
|  | // 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 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: u64) { | 
|  | 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: u64) { | 
|  | 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: u64, 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); | 
|  | } |