Skip to content

Commit

Permalink
lru
Browse files Browse the repository at this point in the history
  • Loading branch information
tickbh committed Jun 14, 2024
1 parent e0e3f2e commit c602ac4
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 1 deletion.
56 changes: 56 additions & 0 deletions benches/lru.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// bench.rs
#![feature(test)]

extern crate test;

use std::mem::replace;
use test::Bencher;

// bench: find the `BENCH_SIZE` first terms of the fibonacci sequence
static BENCH_SIZE: usize = 30;

// recursive fibonacci
fn fibonacci(n: usize) -> u32 {
if n < 2 {
1
} else {
fibonacci(n - 1) + fibonacci(n - 2)
}
}

// iterative fibonacci
struct Fibonacci {
curr: u32,
next: u32,
}

impl Iterator for Fibonacci {
type Item = u32;
fn next(&mut self) -> Option<u32> {
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 }
}

// 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
b.iter(|| {
(0..BENCH_SIZE).map(fibonacci).collect::<Vec<u32>>()
})
}

#[bench]
fn iterative_fibonacci(b: &mut Bencher) {
b.iter(|| {
fibonacci_sequence().take(BENCH_SIZE).collect::<Vec<u32>>()
})
}
49 changes: 49 additions & 0 deletions examples/bench_lru.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use std::collections::hash_map::RandomState;
use std::time::Instant;
use algorithm::{ArcCache, LfuCache, LruCache, LruKCache};

macro_rules! do_test_bench {
($name: expr, $cache: expr, $num: expr, $evict: expr, $data1: expr, $data2: expr) => {
let mut cost = vec![];
let now = Instant::now();
for i in 0..$num {
$cache.insert($data1[i], $data1[i]);
}
cost.push(now.elapsed().as_micros());

let now = Instant::now();
for i in 0..$num {
$cache.get(&$data1[i]);
}
cost.push(now.elapsed().as_micros());

let now = Instant::now();
for i in 0..$num {
$cache.get(&$data2[i]);
}
cost.push(now.elapsed().as_micros());
println!("{} 耗时:{}", $name, cost.iter().map(|v| v.to_string()).collect::<Vec<_>>().join("\t"));
};
}

fn do_bench(num: usize, times: usize) {
let evict = num * 2;
let mut data1 = (0..num).collect::<Vec<_>>();
let mut data2 = vec![];
for _ in 0..evict {
data2.push(rand::random::<usize>() % evict);
}
let mut lru = LruCache::<usize, usize, RandomState>::new(num);
let mut lruk = LruKCache::<usize, usize, RandomState>::new(num);
let mut lfu = LfuCache::<usize, usize, RandomState>::new(num);
let mut arc = ArcCache::<usize, usize, RandomState>::new(num);
do_test_bench!("LruCache", lru, num, evict, &data1, &data2);
do_test_bench!("LruKCache", lruk, num, evict, &data1, &data2);
do_test_bench!("LfuCache", lfu, num, evict, &data1, &data2);
do_test_bench!("ArcCache", arc, num, evict, &data1, &data2);
// println!("耗时:{}", set_timer);
}

fn main() {
do_bench(1e5 as usize, 5);
}
3 changes: 2 additions & 1 deletion src/cache/arc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

use std::{
borrow::Borrow,
collections::{hash_map::RandomState},
collections::hash_map::RandomState,
fmt::{self, Debug},
hash::{BuildHasher, Hash},
ops::{Index, IndexMut},
Expand Down Expand Up @@ -54,6 +54,7 @@ pub struct ArcCache<K, V, S> {
}

impl<K: Hash + Eq, V> ArcCache<K, V, RandomState> {
/// 因为存在四个数组, 所以实际的容量为这个的4倍
pub fn new(cap: usize) -> Self {
ArcCache::with_hasher(cap, RandomState::new())
}
Expand Down

0 comments on commit c602ac4

Please sign in to comment.