-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Performance issues of Caffeine with time based expiration (vs Guava) #1320
Comments
Thanks for taking the time to benchmark and provide your findings. Here are a few observations,
|
Using merge is a bit odd since that is a forced write, whereas computeIfAbsent is usually the behavior that you want. That does a read before falling back to a write if absent or expired, and is what both Guava and Caffeine are optimized for. You can see that while merge is less optimized, those more common cases are faster in your benchmark harness. (Note jmh should still be strongly preferred) MergeGuavaAvg benchmark dur:52921453 CaffeineAvg benchmark dur:60350082 Caffeine without expirationAvg benchmark dur:33437848 PutGuavaAvg benchmark dur:43992562 CaffeineAvg benchmark dur:26648787 Caffeine without expirationAvg benchmark dur:13292782 Compute If AbsentGuavaAvg benchmark dur:45823483 CaffeineAvg benchmark dur:21660199 Caffeine without expirationAvg benchmark dur:8973124 |
Thank you for the detailed reply! The reason we are using merge is that there are multiple threads accessing and updating the cache. Each thread is fetching the latest data from the database and putting the up-to-date entity into the cache. The entities are versioned. Whenever a thread wants to write an entity into the cache we need to ensure that version of the entity is increasing (because otherwise we would be writing a stale value into the cache). You mentioned that |
That sounds like a good reason to use merge, thanks for clarifying. Note that if you are not already using it in Guava, be aware that their computes have had nasty bugs such as corruption or deadlocks. I helped fix a few, but since it is difficult to get fixes merged there are still open items so consider reviewing the bug list. I think the optimization could be applied. It was added to resolve a similar benchmark concern (orbit/orbit#144 (comment)). I don't think you'll run into this as a bottleneck in a non-synthetic benchmark since the application and I/O time, as well as the item distribution, will give the cache enough time to flush the write buffer and hide the latency. It's worth doing to alleviate concerns, but it shouldn't be a blocker for you. |
Got you, makes sense. Just curious, would you have time to help add an optimisation for |
It’s to hard to say given a busy week and the holiday season. I might get to it this weekend, or not. I can’t say tbh. |
Hi,
We are considering using Caffeine in one of our projects where Guava is currently used. Before making the switch we wanted to run a performance experiment against both caches.
When building the cache we are relying on time based expiration:
The benchmark (https://github.com/sfc-gh-emammedov/guava-caffeine-performance-comparison/blob/main/CaffeineVsGuava/src/com/example/cache/CaffeineVsGuavaTest.java) has the following knobs (default setting):
During the tests we noticed that although read operations are faster with Caffeine, write operations are slower. Using IntelliJ profiler we observed that a bunch of time was spent for maintenance related tasks (in this simplified benchmark, it might not be the most expensive operation, but during our internal cache tests, majority of the time was spent in
scheduleDrainBuffers
and eventually during the thread unparking):We tried different executors for Caffeine, but that did not help either. We tried following:
We then tried to remove time based expiration completely and that made the real difference. Caffeine was way faster than Guava then.
Here are the results of benchmark (durations in nanoseconds):
Guava
Caffeine
Caffeine without expiration
We were wondering if this is an expected behaviour for Caffeine when it is configured with time based expiration or whether we are missing some key configuration knob which would make Caffeine performant with time based expiration?
Thank you!
The text was updated successfully, but these errors were encountered: