-
Notifications
You must be signed in to change notification settings - Fork 94
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
[Issue] FusionCache allocates on reads and allocates a lot on writes #185
Comments
Hi @neon-sunset and thanks for your report, I appreciate the time it took you. As you have pointed out other libs do in fact more than Having said that it's important to make sure the perf impact is as small as possible: in the last months I've been quite busy finishing the new Auto-Recovery feature which took a lot of time, and it may be that I haven't paid the needed attention to some extra allocations or cpu cycle spent here and there. I'll try to make sure that the resources needed are as low as possible, and will update you on this later on as soon as I have updates: keep in mind though that to support all the extra features that FusionCache provides (2nd level, fail-safe, auto-recovery, etc), some extra resources are to be accounted for. Meanwhile thanks again for your report! |
I'm mostly worried about avoidable cost caused by some of the internal design decisions that are not necessary to achieve the desired functionality. This library is fairly popular so it is important to ensure that it does not suffer from common cache implementation issues. In particular, Microsoft libraries like One of the key concepts promoted in .NET in the last few years is "pay for play" policy - users should only pay for what they use whenever possible. Thank you for your work. |
I agree, and I'll try to see if I can improve it. eh, I know about this new discussion: I've been part of the old discussion some years ago so I'm writing my thoughts on this new one, will publish them later today.
Totally agree with the concept: on a pragmatic note though, with the time and resources available to me (it's an oss work done in my spare time), personally I tried to find the right balance between adding useful features that cover various scenarios and common production problems with performance and resource allocation. It's not always easy as you can imagine, but I'll strive to make it even better in the future.
Thanks to you for sharing your thoughts, it's good to see participation! |
Oh, one thing I'd like to add that may have been missing here, is that currently FusionCache is based on the 2 main caching abstraction in .net, Having said that, while there's a huge value in being able to use any implementation of As said I've been experimenting from some time with this approach, but currently have nothing to see yet, will update. ps: is FastCache usable for heterogeneous data or just homogeneous? Meaning, can I use it for different types of data in the same cache (maybe by just using it with Thanks. |
Hi @neon-sunset , I just finished a big effort in reducing cpu usage and memory allocation, and I pushed all the changes in the release/v1_0_0 branch. First of all I'd like to thanks you again for opening this issue and pointing out some perf shortcoming that FusionCache had: lately I've been very busy with completing the last big features (the new Auto-Recovery, Open Telemetry support, etc), preparing for an On .NET episode and finishing the last touches for the big Having said that, what you pointed out is important, so I finally took some time to go allocation hunting and trying to optimize whatever I could in the common happy paths: I'm happy to report that I've been able to get some really nice results, which I'd like to show (again using your own benchmark code). SetBefore:
After:
As you can see I've been able to drop the cpu usage by about The allocations instead dropped by GetBefore:
After:
Here cpu went down about Allocations instead became awesome: they dropped to a beautiful zero, so no more allocations (damn closures). ConclusionsThis is not the end of the optimization story, and now that all the main features (and then some) are there and Of course, as you pointed out yourself, while the other caches are memory ( All of this to say that, while the "pay for play" policy is something I absolutely agree on it's also fair to say that with all these features, even just the various "is null/enabled" checks here and there for each feature + a minimum of extra memory for the needed metadata in support of them, it will always be a kind of apples to oranges comparison, in a way. I'm interested in knowing what you think, if you'd like. Meanwhile, again thanks! |
Awesome! The reductions in memory usage are welcome and will help with reducing the churn on load spikes. As for you asking whether FastCache is usable within FusionCache - at this point I'm regretting quite aggressive design decision to make it a global static cache, it definitely does not fit together well with FusionCache which is instanced and isolated in a more, you could say, reasonable way. Maybe in the future in some version 2.0 this will change but I just don't have time for this at the moment unfortunately. The idea of very thin layer on top of Therefore, if you think it's worth investing the effort, As for your note regarding the inherent cost of internal and external abstractions, there are a couple of points I wanted to share which may be of interest to you:
Watching the episode right now :) |
Thanks for all the info, really damn interesting. Will definitely try the AOT benchmark: I was already curious and now even more 😬 About the second point: do you have maybe some material about that? Blog post, a docs page, examples, anything really. Thanks again, and if you like let me know how about the episode. |
Hi all, I just released Please give it a try, thanks! |
Hi all, I've finally released v1.0 🥳 Feels a little unreal tbh, but yep: v1.0 is out. |
Describe the issue
See numbers below. There are other issues like cache line pollution on reads through interlocked applied to a singular location which will ruin the scaling on many-core systems but I wanted to start with bringing attention to the implementation flaws in the first place.
In the outlined scenario of in-memory cache,
FusionCache
comes last and allocates significantly more than all other options. WhileFastCache
is very focused at doing a singular task (in-memory cache with per-item expiration and eviction) that allows it to be as fast as is technically possible,MemoryCache
andLazyCache
have much more features and still allocate much less.Unrelated but somewhat amusing is that OpenJDK improves by 10% at most between 17 and 21, and .NET sees 20-40% speed-up after just a single LTS version bump.
Benchmark code
Reads:
Writes
The text was updated successfully, but these errors were encountered: