根据这些微基准,事实证明,Caffeine在读取和写入操作方面都比Guava 缓存快。
Caffeine 实施的秘诀是什么?它与 Guava Cache 有何不同?
我是否正确,如果咖啡因定时到期,请使用预定的执行程序在后台执行适当的维护操作?
主要区别在于 Caffeine 使用环形缓冲区来记录和回放事件,而 Guava 使用ConcurrentLinkedQueue
. 其目的始终是迁移 Guava,从更简单的开始是有意义的,但不幸的是,人们从来没有兴趣接受这些更改。环形缓冲区方法避免了分配,有界(有损),并且操作起来更便宜。
剩余成本是由于设计不匹配造成的。的原作者MapMaker
热衷于通过将软引用推迟到 GC 来解决缓存问题。不幸的是,虽然这在微基准测试中看起来很快,但由于导致停止世界的 GC 抖动,它在实践中的性能很糟糕。基于尺寸的解决方案必须适应这项工作,这并不理想。Caffeine 针对基于大小进行了优化,并且还获得了改进的哈希表,而 Guava 更优雅地处理引用缓存。
咖啡因不会为维护或过期创建自己的线程。它确实将成本推迟到commonPool
,这略微改善了面向用户的延迟,但没有改善吞吐量。未来的版本可能会利用CompletableFuture.delayedExecutor
来安排下一个到期事件,而无需直接创建线程(对于具有依赖于提示删除通知的业务逻辑的用户)。
ConcurrentLinkedHashMap
并且MapMaker
是同时编写的,CLHM 与 Caffeine 具有相似的性能。我相信差异是由于设计师偏爱和优化的场景,这影响了其他功能的实现方式。让番石榴具有相似的性能特征是很容易实现的,但没有内部支持者来推动这一点(更不用说咖啡因作为一种受欢迎的替代品)。