diff --git a/benches/lru.rs b/benches/lru.rs index bb567b6..56f0604 100644 --- a/benches/lru.rs +++ b/benches/lru.rs @@ -3,54 +3,49 @@ extern crate test; -use std::mem::replace; +use algorithm::{ArcCache, LfuCache, LruCache, LruKCache}; use test::Bencher; -// bench: find the `BENCH_SIZE` first terms of the fibonacci sequence -static BENCH_SIZE: usize = 30; +static BENCH_SIZE: usize = 10000; -// recursive fibonacci -fn fibonacci(n: usize) -> u32 { - if n < 2 { - 1 - } else { - fibonacci(n - 1) + fibonacci(n - 2) - } +macro_rules! do_test_bench { + ($cache: expr) => { + for i in 0..BENCH_SIZE { + $cache.insert(i, i); + $cache.get(&i); + } + }; } - -// iterative fibonacci -struct Fibonacci { - curr: u32, - next: u32, +#[bench] +fn calc_lru(b: &mut Bencher) { + b.iter(|| { + let mut lru = LruCache::new(BENCH_SIZE / 2); + do_test_bench!(lru); + }) } -impl Iterator for Fibonacci { - type Item = u32; - fn next(&mut self) -> Option { - let new_next = self.curr + self.next; - let new_curr = replace(&mut self.next, new_next); - - Some(replace(&mut self.curr, new_curr)) - } -} -fn fibonacci_sequence() -> Fibonacci { - Fibonacci { curr: 1, next: 1 } +#[bench] +fn calc_lruk(b: &mut Bencher) { + b.iter(|| { + let mut lruk = LruKCache::new(BENCH_SIZE / 2); + do_test_bench!(lruk); + }) } -// function to benchmark must be annotated with `#[bench]` #[bench] -fn recursive_fibonacci(b: &mut Bencher) { - // exact code to benchmark must be passed as a closure to the iter - // method of Bencher +fn calc_lfu(b: &mut Bencher) { b.iter(|| { - (0..BENCH_SIZE).map(fibonacci).collect::>() + let mut lfu = LfuCache::new(BENCH_SIZE / 2); + do_test_bench!(lfu); }) } #[bench] -fn iterative_fibonacci(b: &mut Bencher) { +fn calc_arc(b: &mut Bencher) { b.iter(|| { - fibonacci_sequence().take(BENCH_SIZE).collect::>() + let mut arc = ArcCache::new(BENCH_SIZE / 2); + do_test_bench!(arc); }) -} \ No newline at end of file +} + diff --git a/examples/bench_lru.rs b/examples/bench_lru.rs index 883f140..a1ac5f3 100644 --- a/examples/bench_lru.rs +++ b/examples/bench_lru.rs @@ -19,10 +19,11 @@ macro_rules! do_test_bench { } } cost.push(now.elapsed().as_micros()); - println!("{}\t{}\t{:.2}%", $name, cost.iter().map(|v| v.to_string()).collect::>().join("\t"), hit as f64 * 100.0 / all as f64); + println!("|{}|{}|{:.2}%|", $name, cost.iter().map(|v| v.to_string()).collect::>().join("\t"), hit as f64 * 100.0 / all as f64); }; } +#[allow(dead_code)] fn build_order_data(num: usize) -> Vec<(usize, usize)> { let mut data = vec![]; for i in 0..num { @@ -32,11 +33,11 @@ fn build_order_data(num: usize) -> Vec<(usize, usize)> { data } +#[allow(dead_code)] fn build_freq_data(num: usize) -> Vec<(usize, usize)> { let mut data = vec![]; for i in 0..num { data.push((i, i + 1)); - // data.push((i+1, i + 2)); let ridx = i / 4 + 1; for _ in 0..1 { data.push((rand::random::() % ridx, 0)); @@ -45,19 +46,38 @@ fn build_freq_data(num: usize) -> Vec<(usize, usize)> { data } + +#[allow(dead_code)] +fn build_high_freq_data(num: usize) -> Vec<(usize, usize)> { + let mut data = vec![]; + for i in 0..num { + data.push((i, i + 1)); + let ridx = (i / 4 + 1).min(1000); + for _ in 0..10 { + data.push((rand::random::() % ridx, 0)); + } + for _ in 0..5 { + data.push((i + num + rand::random::() % num, i + 1)); + } + } + data +} + fn do_bench(num: usize) { let evict = num * 2; let mut lru = LruCache::::new(num); let mut lruk = LruKCache::::new(num); let mut lfu = LfuCache::::new(num); let mut arc = ArcCache::::new(num / 2); - println!("名字\t耗时\t命中率\t"); - let order_data = build_freq_data(evict); - do_test_bench!("LruCache", lru, num, evict, &order_data); - // do_test_bench!("LruKCache", lruk, num, evict, &order_data); - do_test_bench!("LfuCache", lfu, num, evict, &order_data); - // do_test_bench!("ArcCache", arc, num, evict, &order_data); - // println!("耗时:{}", set_timer); + println!("|名字|耗时|命中率|"); + println!("|---|---|---|"); + // let data = build_freq_data(evict); + let data = build_high_freq_data(evict); + // let data = build_order_data(evict); + do_test_bench!("LruCache", lru, num, evict, &data); + do_test_bench!("LruKCache", lruk, num, evict, &data); + do_test_bench!("LfuCache", lfu, num, evict, &data); + do_test_bench!("ArcCache", arc, num, evict, &data); } fn main() {