-
Notifications
You must be signed in to change notification settings - Fork 936
Eliminate unnecessary AsyncLocal allocation if SessionId isn't changed #1453
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
Conversation
After running a profiler it seems that this solution isn't viable. At the current state the performance improvement is only 1.53% |
…> on Full .NET Fx
I turns out that @fredericDelaporte @gliljas @maca88 could you please double check? |
|
||
namespace NHibernate.Impl | ||
{ | ||
public class SessionIdLoggingContext : IDisposable | ||
{ | ||
private static readonly AsyncLocal<Guid?> _currentSessionId = new AsyncLocal<Guid?>(); | ||
|
||
#if NETSTANDARD2_0 || NETCOREAPP2_0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.net standard and .net core do not support CallContext
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking that CallContext
was not suitable for async
, but it appears its Logical
methods are ok. (According to this, not only they were suitable for our "linear" usage case (no tasks launched in parallel on same session), but since .Net 4.5 they are also suitable in any async usage case.)
So the main points to consider are in my view:
- Whether we accept introducing those target framework directives for this case, or if we prefer avoid them as much as possible (so wait for maca solution to be released or for another one).
- Is it still worth checking the value has changed before setting it? The main overhead seems to be having the context containing some data, which then gets copied at each context switch anyway.
- If putting this solution in place, does maca solution still provides additional significant savings? If session id is actually responsible of 28.35% of timings as said in #1446, then it looks probable. But if maca solution does not add additional significant savings compared to this one here, then maybe should it be reverted.
I want this change to be introduced in a bugfix release (and release it sooner).
I introduced them beforehand as I know we're working on the .net standard version.
Yes. We already read the old value to store it for the future, so no extra overhead there. Then it saves us the Dispose call. So in the first version, it 1.8% of performance. Apparently reading the context is most expensive operation.
Yeah, this overhead is still here, but it's much less than the overhead of
Yes, as above - the most expensive operation is reading the context. And we still have it here. As you've noted its 18% (here) vs 28% (when completely disabled). So we need to merge these solutions together. |
@hazzik I did some testing and it's working fine. 👍 |
Hi @StephenCleary I’ve seen your comment on SO about the performance of |
@hazzik From the source code, I just don't see how that's possible. |
@StephenCleary most of the CPU is wasted in dictionary operations in ExecutionContext. I don't know where the allocations are coming from. But the fact is, that with |
Maybe this copying of the dictionary is responsible: https://referencesource.microsoft.com/#mscorlib/system/threading/executioncontext.cs,683. Also, bear in mind, that in that particular case we do not have any context switches, as everything is happening synchronously in a single thread. |
This might fix the unnecessary allocations~, but I've never checked that~.