Основное отличие состоит в том, что Caffeine использует кольцевые буферы для записи и воспроизведения событий, тогда как Guava использует ConcurrentLinkedQueue
.Намерение всегда заключалось в том, чтобы перенести Гуаву поверх, и было бы разумно начать проще, но, к сожалению, не было никакого интереса принять эти изменения.Подход с кольцевым буфером позволяет избежать выделения, является ограниченным (с потерями) и обходится дешевле.
Остальные затраты обусловлены несоответствием проекта.Первоначальный автор MapMaker
с энтузиазмом относился к мягким ссылкам как к решению проблем с кэшированием, откладывая его в GC.К сожалению, хотя это может показаться быстрым в микробенчмарках, на практике оно имеет ужасную производительность из-за того, что вызывает остановку ГХ.Решение, основанное на размере, должно быть адаптировано к этой работе, и это не идеально.Caffeine оптимизируется под размер, а также получает улучшенную хеш-таблицу, тогда как Guava более элегантно обрабатывает кэширование ссылок.
Caffeine не создает свои собственные потоки для обслуживания или истечения срока действия.Это действительно переносит стоимость на commonPool
, что немного увеличивает задержки, с которыми сталкиваются пользователи, но не увеличивает пропускную способность.В будущей версии может использоваться CompletableFuture.delayedExecutor
для планирования следующего события с истечением срока действия без непосредственного создания потоков (для пользователей, чья бизнес-логика зависит от уведомлений о быстром удалении).
ConcurrentLinkedHashMap
и MapMaker
были записаны одновременновремя и CLHM имеет аналогичные характеристики с кофеином.Я полагаю, что разница заключается в том, какие сценарии предпочитали и оптимизировали дизайнеры, что повлияло на реализацию других функций.Есть низко висящие фрукты, которые позволяют Guava иметь схожий профиль производительности, но нет внутреннего чемпиона, который мог бы управлять этим (и тем более с кофеином в качестве предпочтительной альтернативы).