Remove some allocations related to storing CacheEntry scopes#45563
Remove some allocations related to storing CacheEntry scopes#45563adamsitnik merged 4 commits intodotnet:masterfrom
Conversation
|
Tagging subscribers to this area: @eerhardt, @maryamariyan Issue DetailsWhile looking at the source code to address #45436 I've realized that the This led me to the conclusion, that there is no need to have this type if all it does is just being a wrapper around a single The Doing this a little bit later than before allowed to avoid expensive access to Benchmark numbers:
Contributes to #45436
|
|
This is going to require a very careful review, AsyncLocal's have a lot of surprising behaviors that often require special handling like this. |
| } | ||
| } | ||
|
|
||
| CacheEntryHelper.ExitScope(this, _previous); |
There was a problem hiding this comment.
Is there any way changing the ordering between popping the "scope" off the stack and calling _cache.SetEntry could break anything? Before the scope was removed before calling _cache.SetEntry. Now it happens after.
There was a problem hiding this comment.
So far, when Dispose was called, we were first setting the CacheEntryHelper.Current to previous and then accessing CacheEntryHelper.Current again to get it. With my change, we take advantage of knowing "previous" and resetting it after using its value (one access to async local instead of two).
I don't think that this reordering can break anything.
src/libraries/Microsoft.Extensions.Caching.Memory/src/CacheEntryHelper.cs
Outdated
Show resolved
Hide resolved
…ryHelper.cs Co-authored-by: Eric Erhardt <eric.erhardt@microsoft.com>
eerhardt
left a comment
There was a problem hiding this comment.
LGTM. (I thought I had already approved this)
|
@Tratcher could you please review it? |
|
I've asked @davidfowl to review this one instead. |
|
I want to send one more PR that would conflict with this one. Since I have two approvals and @davidfowl seems to be busy, I am going to merge it now. |
|
I had a comment but I never sent it. The use of async locals outside of async method is suspect but isn't new. The ordering change also concerns me but I haven't spend enough time coming up with hypothetical scenarios it might affect. I'd look to see what user code runs before and after our set/unset to see if there's any change more things are being captured now. |
@davidfowl thank you for your feedback, I've sent #45964 to address it. |
While looking at the source code to address #45436 I've realized that the
_previousfield of theCacheEntryStacktype is never used:runtime/src/libraries/Microsoft.Extensions.Caching.Memory/src/CacheEntryStack.cs
Lines 8 to 38 in 4487088
This led me to the conclusion, that there is no need to have this type if all it does is just being a wrapper around a single
CacheEntryinstance. So instead ofAsyncLocal<CacheEntryStack>we can haveAsyncLocal<CacheEntry>The
ScopeLeaseresponsibility was to just reset theCurrentduring Dispose. To save some allocation we can just "inline" this type and do what it did inCacheEntry.Dispose:runtime/src/libraries/Microsoft.Extensions.Caching.Memory/src/CacheEntryHelper.cs
Lines 59 to 62 in 4487088
Doing this a little bit later than before allowed to avoid expensive access to
CacheEntryHelper.CurrentinCacheEntry.DisposeBenchmark numbers:
Contributes to #45436