#lru-cache #cache #lru

quick_cache

轻量级且高性能的并发缓存

19个版本

0.6.3 2024年8月19日
0.6.2 2024年7月25日
0.5.2 2024年7月25日
0.4.2 2024年3月24日
0.1.1 2022年8月16日

13 in 缓存

Download history 23051/week @ 2024-05-03 27074/week @ 2024-05-10 27600/week @ 2024-05-17 29391/week @ 2024-05-24 31851/week @ 2024-05-31 26606/week @ 2024-06-07 41897/week @ 2024-06-14 49738/week @ 2024-06-21 42542/week @ 2024-06-28 39172/week @ 2024-07-05 42782/week @ 2024-07-12 49115/week @ 2024-07-19 52664/week @ 2024-07-26 50192/week @ 2024-08-02 63754/week @ 2024-08-09 58022/week @ 2024-08-16

234,334 每月下载量
94 个crates(27直接) 中使用

MIT 许可证

145KB
3K SLoC

Quick Cache

Crates.io Docs CI

针对低缓存开销优化的轻量级且高性能的并发缓存。

  • 与并发哈希表相比,开销较小
  • 可扫描和命中率高的缓存策略
  • 每项用户定义的权重
  • 与线程数量很好地扩展
  • 使用 get_or_insertget_value_or_guard 函数执行原子操作
  • 使用 get_or_insert_asyncget_value_or_guard_async 函数执行原子异步操作
  • 支持项固定
  • 有效地处理零权重项
  • 允许自定义生命周期挂钩(例如,可以用于实现驱逐监听器)
  • 不使用后台线程
  • 仅使用不安全的非常简单的用法
  • 小的依赖关系树

实现针对缓存访问时间和开销累积到显著成本的用例进行了优化。一些功能如:生存时间、迭代器、事件监听器等在Quick Cache中部分或未实现。如果您需要这些功能,您可以查看Moka crate。

示例

基本用法

use quick_cache::unsync::Cache;

fn main() {
    let cache = Cache::new(5);
    cache.insert("square", "blue");
    cache.insert("circle", "black");
    assert_eq!(*cache.get(&"square").unwrap(), "blue");
    assert_eq!(*cache.get(&"circle").unwrap(), "black");
}

具有自定义项权重的缓存。在这种情况下,根据值的字符串长度。

use quick_cache::{Weighter, sync::Cache};

#[derive(Clone)]
struct StringWeighter;

impl Weighter<u64, String> for StringWeighter {
    fn weight(&self, _key: &u64, val: &String) -> u64 {
        // Be cautions out about zero weights!
        val.len() as u64
    }
}

fn main() {
    let cache = Cache::with_weighter(100, 100_000, StringWeighter);
    cache.insert(1, "1".to_string());
    cache.insert(54, "54".to_string());
    cache.insert(1000, "1000".to_string());
    assert_eq!(cache.get(&1000).unwrap(), "1000");
}

使用 Equivalent 特性进行复杂键

use quick_cache::{sync::Cache, Equivalent};

#[derive(Debug, Hash)]
pub struct Pair<A, B>(pub A, pub B);

impl<A, B, C, D> Equivalent<(C, D)> for Pair<A, B>
where
    A: PartialEq<C>,
    B: PartialEq<D>,
{
    fn equivalent(&self, rhs: &(C, D)) -> bool {
        self.0 == rhs.0 && self.1 == rhs.1
    }
}

fn main() {
    let cache: Cache<(String, i32), String> = Cache::new(5);
    cache.insert(("square".to_string(), 2022), "blue".to_string());
    cache.insert(("square".to_string(), 2023), "black".to_string());
    assert_eq!(cache.get(&Pair("square", 2022)).unwrap(), "blue");
}

基准测试

由于这个crate以性能为导向,因此需要进行一些比较。尽管如此,基准测试可能会误导,所以请带着一点怀疑态度看待所有内容。

在x64 Linux操作系统 + Intel i9-12900H CPU上使用 mokabench 执行的基准测试。

跟踪1(来自Arc论文的S3)

缓存 最大容量 客户端 命中率(%) 耗时(s)
HashLink (LRU w/ Mutex) 100000 1 2.327 2.479
HashLink (LRU w/ Mutex) 100000 3 2.327 6.171
HashLink (LRU w/ Mutex) 100000 6 2.328 12.467
QuickCache Sync Cache 100000 1 12.764 2.465
QuickCache Sync Cache 100000 3 12.765 1.387
QuickCache Sync Cache 100000 6 12.764 0.835
Mini Moka Sync Cache 100000 1 10.436 10.473
Mini Moka Sync Cache 100000 3 10.541 8.439
Mini Moka Sync Cache 100000 6 10.366 8.008
HashLink (LRU w/ Mutex) 400000 1 12.039 2.956
HashLink (LRU w/ Mutex) 400000 3 12.041 6.939
HashLink (LRU w/ Mutex) 400000 6 12.043 13.503
QuickCache Sync Cache 400000 1 42.044 3.250
QuickCache Sync Cache 400000 3 42.044 1.299
QuickCache Sync Cache 400000 6 42.044 0.777
Mini Moka Sync Cache 400000 1 42.544 9.671
Mini Moka Sync Cache 400000 3 41.525 7.052
Mini Moka Sync Cache 400000 6 41.007 6.618
HashLink (LRU w/ Mutex) 800000 1 56.600 3.221
HashLink (LRU w/ Mutex) 800000 3 56.603 5.921
HashLink (LRU w/ Mutex) 800000 6 56.605 12.768
QuickCache Sync Cache 800000 1 66.801 3.980
QuickCache Sync Cache 800000 3 66.802 1.418
QuickCache Sync Cache 800000 6 66.803 0.798
Mini Moka Sync Cache 800000 1 70.304 10.613
Mini Moka Sync Cache 800000 3 68.054 4.754
Mini Moka Sync Cache 800000 6 66.288 4.137

跟踪2(来自Arc论文的DS1)

缓存 最大容量 客户端 命中率(%) 耗时(s)
HashLink (LRU w/ Mutex) 1000000 1 3.086 10.097
HashLink (LRU w/ Mutex) 1000000 3 3.085 22.443
HashLink (LRU w/ Mutex) 1000000 6 3.082 41.351
QuickCache Sync Cache 1000000 1 15.052 9.426
QuickCache Sync Cache 1000000 3 15.059 4.139
QuickCache Sync Cache 1000000 6 15.078 2.467
Mini Moka Sync Cache 1000000 1 14.910 28.974
Mini Moka Sync Cache 1000000 3 13.257 24.681
Mini Moka Sync Cache 1000000 6 13.518 22.759
HashLink (LRU w/ Mutex) 4000000 1 20.245 9.863
HashLink (LRU w/ Mutex) 4000000 3 20.250 19.418
HashLink (LRU w/ Mutex) 4000000 6 20.259 36.932
QuickCache Sync Cache 4000000 1 44.565 9.083
QuickCache Sync Cache 4000000 3 44.574 4.272
QuickCache Sync Cache 4000000 6 44.569 2.449
Mini Moka Sync Cache 4000000 1 45.398 31.108
Mini Moka Sync Cache 4000000 3 44.236 21.381
Mini Moka Sync Cache 4000000 6 41.723 18.719
HashLink (LRU w/ Mutex) 8000000 1 43.035 9.751
HashLink (LRU w/ Mutex) 8000000 3 43.034 16.554
HashLink (LRU w/ Mutex) 8000000 6 43.031 34.978
QuickCache Sync Cache 8000000 1 71.124 7.675
QuickCache Sync Cache 8000000 3 71.139 3.198
QuickCache Sync Cache 8000000 6 71.143 2.348
Mini Moka Sync Cache 8000000 1 67.447 28.462
Mini Moka Sync Cache 8000000 3 67.995 17.054
Mini Moka Sync Cache 8000000 6 64.738 12.929

参考文献

许可证

本项目受MIT许可证许可。

依赖关系

~2–26MB
~355K SLoC