根据这些micro benchmarks,事实证明Caffeine在读取和写入操作中都比Guava cache快。
咖啡因实现的 secret 是什么?它与Guava缓存有何不同?
如果时间到期,Caffeine是否可以使用预定的执行程序在后台执行适当的维护操作,对吗?
最佳答案
主要区别是因为Caffeine使用环形缓冲区来记录和重播事件,而Guava使用ConcurrentLinkedQueue
。目的总是要迁移 Guava ,并且开始更简单是有意义的,但是不幸的是,从来没有兴趣接受这些更改。环形缓冲区方法避免了分配,是有界的(有损),并且操作起来更便宜。
剩余成本是由于设计不匹配造成的。 MapMaker
的原始作者热衷于将软引用作为缓和问题的解决方案,方法是将其推迟到GC。不幸的是,虽然在微基准测试中看似很快,但由于引起了世界各地的GC颠簸,它在实践中的性能令人震惊。基于大小的解决方案必须适应这项工作,这并不理想。咖啡因针对基于大小的文件进行了优化,并且还获得了改进的哈希表,而 Guava 则更优雅地处理了引用缓存。
咖啡因不会创建自己的线程来进行维护或到期。确实将成本推迟到commonPool
,这会稍微提高面向用户的延迟,但不会提高吞吐量。将来的版本可能会使用CompletableFuture.delayedExecutor
来调度下一个到期事件,而无需直接创建线程(对于具有业务逻辑的用户(取决于提示删除通知))。ConcurrentLinkedHashMap
和MapMaker
是同时编写的,CLHM与咖啡因的性能相似。我认为差异是由于设计人员偏爱和优化了哪些方案而影响了其他功能的实现方式。垂死的果实可以使 Guava 具有类似的性能表现,但没有一个内部冠军可以 push 这一发展(以咖啡因为首选替代品更是如此)。
关于caching - 咖啡因与 Guava 缓存,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55494488/