From bf09388604224bdebd63db622829015578fddd85 Mon Sep 17 00:00:00 2001 From: Timothy Warren Date: Fri, 21 Feb 2020 16:33:00 -0500 Subject: [PATCH] Attempt to benchmark gcd algorithm --- benches/stock_functions.rs | 42 ++++++++++++++++++++++++++++++-------- src/num.rs | 15 ++++++++++++++ 2 files changed, 48 insertions(+), 9 deletions(-) diff --git a/benches/stock_functions.rs b/benches/stock_functions.rs index 2255c29..f920b18 100644 --- a/benches/stock_functions.rs +++ b/benches/stock_functions.rs @@ -1,4 +1,5 @@ use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion}; +use rusty_numbers::num::Unsigned; use rusty_numbers::{factorial, fibonacci, it_factorial, mem_fibonacci, rec_fibonacci}; fn bench_factorial(c: &mut Criterion) { @@ -6,10 +7,10 @@ fn bench_factorial(c: &mut Criterion) { for i in [0usize, 5, 10, 15, 20, 25, 30, 34].iter() { group.bench_with_input(BenchmarkId::new("Recursive naive", i), i, |b, i| { - b.iter(|| factorial(*i)) + b.iter(|| factorial(black_box(*i))) }); group.bench_with_input(BenchmarkId::new("Iterative", i), i, |b, i| { - b.iter(|| it_factorial(*i)) + b.iter(|| it_factorial(black_box(*i))) }); } group.finish(); @@ -18,26 +19,49 @@ fn bench_factorial(c: &mut Criterion) { fn bench_fibonacci(c: &mut Criterion) { let mut group = c.benchmark_group("Fibonacci"); - for i in [0usize, 5, 10, 15, 20, 30].iter() { + for i in [0usize, 10, 20, 30, 40, 50, 70, 93, 140, 186].iter() { group.bench_with_input(BenchmarkId::new("Recursive memoized", i), i, |b, i| { - b.iter(|| mem_fibonacci(*i)) + b.iter(|| mem_fibonacci(black_box(*i))) }); - // group.bench_with_input(BenchmarkId::new("Recursive naive", i), i, |b, i| b.iter(|| rec_fibonacci(*i))); group.bench_with_input(BenchmarkId::new("Iterative", i), i, |b, i| { - b.iter(|| fibonacci(*i)) + b.iter(|| fibonacci(black_box(*i))) }); } group.finish(); let mut group = c.benchmark_group("Recursive Fibonacci"); - for i in [0usize, 5, 10, 15, 20, 25, 26, 27, 28, 29, 30].iter() { + for i in [0usize, 10, 20, 25, 26, 27, 28, 29, 30].iter() { group.bench_with_input(BenchmarkId::new("Naive Recursive", i), i, |b, i| { - b.iter(|| rec_fibonacci(*i)) + b.iter(|| rec_fibonacci(black_box(*i))) }); } group.finish(); } -criterion_group!(benches, bench_factorial, bench_fibonacci); +fn bench_gcd(c: &mut Criterion) { + let mut group = c.benchmark_group("GCD"); + + let max = fibonacci(186).unwrap(); + let max_1 = fibonacci(185).unwrap(); + + let med = fibonacci(93).unwrap(); + let med_1 = fibonacci(92).unwrap(); + + let small = fibonacci(15).unwrap(); + let small_1 = fibonacci(14).unwrap(); + + for input in [(small_1, small), (med_1, med), (max_1, max)].iter() { + let param = format!("{},{}", input.0, input.1); + group.bench_with_input(BenchmarkId::new("Binary", ¶m), input, |b, input| { + b.iter(|| u128::gcd(black_box(input.0), black_box(input.1))) + }); + group.bench_with_input(BenchmarkId::new("Euclid", ¶m), input, |b, input| { + b.iter(|| u128::e_gcd(black_box(input.0), black_box(input.1))) + }); + } + group.finish(); +} + +criterion_group!(benches, bench_factorial, bench_fibonacci, bench_gcd); criterion_main!(benches); diff --git a/src/num.rs b/src/num.rs index e28d0ed..1b554b8 100644 --- a/src/num.rs +++ b/src/num.rs @@ -108,6 +108,9 @@ pub trait Unsigned: /// Find the greatest common denominator of two numbers fn gcd(a: Self, b: Self) -> Self; + /// Euclid gcd algorithm + fn e_gcd(a: Self, b: Self) -> Self; + /// Find the least common multiple of two numbers fn lcm(a: Self, b: Self) -> Self; } @@ -205,6 +208,17 @@ macro_rules! impl_unsigned { Self::gcd((b - a) >> 1, a) } + fn e_gcd(x: $Type, y: $Type) -> $Type { + let mut x = x; + let mut y = y; + while y != 0 { + let t = y; + y = x % y; + x = t; + } + x + } + fn lcm(a: $Type, b: $Type) -> $Type { if (a == 0 && b == 0) { return 0; @@ -254,6 +268,7 @@ mod tests { assert_eq!(u8::gcd(2, 2), 2); assert_eq!(u8::gcd(2, 8), 2); assert_eq!(u16::gcd(36, 48), 12); + assert_eq!(u16::e_gcd(36, 48), 12); } #[test]