#lru-cache #cache #lru #capacity #items #flip

无 std fliplru

一个显示缓存容量有效性的 LRU 缓存

7 个版本

0.1.6 2023 年 7 月 25 日
0.1.5 2023 年 7 月 25 日

#121缓存

Download history 172/week @ 2024-03-11 137/week @ 2024-03-18 98/week @ 2024-03-25 164/week @ 2024-04-01 199/week @ 2024-04-08 181/week @ 2024-04-15 81/week @ 2024-04-22 155/week @ 2024-04-29 179/week @ 2024-05-06 165/week @ 2024-05-13 104/week @ 2024-05-20 89/week @ 2024-05-27 120/week @ 2024-06-03 56/week @ 2024-06-10 47/week @ 2024-06-17 106/week @ 2024-06-24

每月 下载 332

MIT 许可证

17KB
176

fliplru

flip LRU 是一个具有一些内置分析功能的 LRU 缓存,以帮助调整缓存容量。

此缓存数据结构的目标有两个

  1. get API 应该快速且开销低,因为它是缓存的主要 API。
  2. 公开一些分析指标,以帮助确定适当的容量。

还有一个目标,但与实现相关,我不想使用链表。

实现基于 2 个哈希表来提供 LRU 功能。因此,此缓存的总体容量是 2*cap LRU 项目。保证 cap LRU 项目将在缓存中。从 cap+12*cap 的 LRU 项目可能在缓存中,但这没有保证。

使用 hashbrown 映射和 2 个缓存设计一起提供快速的 get API。

公开一个翻转指标,以帮助调整缓存容量。翻转表示缓存容量达到的次数。它清空缓存并重新填充,以使性能不受影响(请参阅下面的基准测试)。如果翻转计数为 0,则缓存过大。如果翻转计数非常高,并且接近访问次数/容量,则缓存未得到有效利用,并且需要增加容量。

API 启发于 lru,由 Jerome Froelich 开发。


检查缓存容量是否太小,无法用于用例

以下是一个检查缓存的容量是否配置过小的示例。在这个例子中,缓存被访问了 20 次,对于容量为 2 的缓存,翻转计数为 8。这表明对于访问模式没有发生缓存。

let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
for i in 0..5 {
    cache.put(i, i);
}
for i in 0..20 {
    cache.get(&(i % 5));
}

assert_eq!(cache.get_flips(), 8);

检查缓存容量是否过大,无法用于用例

以下是一个检查缓存是否配置了足够容量的示例。在这个示例中,缓存被访问了20次,对于容量为5的缓存,翻转次数为0。这表明缓存完全满足每次访问。

let mut cache = LruCache::new(NonZeroUsize::new(5).unwrap());
for i in 0..5 {
    cache.put(i, i);
}
for i in 0..20 {
    cache.get(&(i % 5));
}

assert_eq!(cache.get_flips(), 0);

状态

这是一个基本的LRU缓存,带有帮助调整缓存容量的指标。提供快速的get API。

基准测试

基准测试受到了Christian Mauduit的HashLRU的启发。

使用各种缓存实现配置的100000容量进行get API的基准测试比较。这在一个2020年的MacBook Air上运行。

running 8 tests
test tests::bench_read_usize_builtin_hashmap    ... bench:          16 ns/iter (+/- 0)
test tests::bench_read_usize_caches             ... bench:          37 ns/iter (+/- 16)
test tests::bench_read_usize_fastlru            ... bench:          48 ns/iter (+/- 7)
test tests::bench_read_usize_fliplru            ... bench:           7 ns/iter (+/- 0)
test tests::bench_read_usize_hashlru_cache      ... bench:          10 ns/iter (+/- 1)
test tests::bench_read_usize_hashlru_sync_cache ... bench:          15 ns/iter (+/- 0)
test tests::bench_read_usize_lru                ... bench:          10 ns/iter (+/- 0)
test tests::bench_read_usize_lru_cache          ... bench:          38 ns/iter (+/- 0)

test result: ok. 0 passed; 0 failed; 0 ignored; 8 measured; 0 filtered out; finished in 14.09s

要运行基准测试

cd bench
rustup default nightly
cargo bench

依赖关系

~2MB
~26K SLoC