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
Fix lock contention #941 #906 #953
Conversation
It's possible to create some sort of benchmark to test both old and new implementations? Do you have any screenshots from concurrency visualizer comparing the two? |
No.
Used https://github.com/danielpalme/IocPerformance
Host:
|
Thanks for putting together another good PR @avtc. I wrote a quick multi threading test that could be used for some profiling and to visualize the concurrency improvements. It does 1,000,000 resolve operations as 10,000 resolves across 100 concurrent tasks. In the screen capture below is the current code without the PR. I have highlighted Lock contention and there is plenty to be seen (the test was designed to really highlight the bottleneck). The total duration is around 347ms but this is with the profiler attached and should only be used as an indicator for comparison to the following run that also has the profiler attached. As expected the reduced locking definitely helps when concurrency comes into play. The screen capture below is with the changes in the PR. There is some lock contention up front as seen above, but after that locking is eliminated and the total time is around 160ms. I ran the same benchmarks and below is the 4.9.0 baseline on my machine.
Here is the run with the changes and most things look better (the multi tests in particular).
Without the
I was going to leave this PR for after the |
Looks like a great change. Just wondering - instead of calling |
} | ||
|
||
_preserveDefaultImplementations.Add(registration); | ||
var newPreserveDefaultImplementations = new List<IComponentRegistration>(Volatile.Read(ref _preserveDefaultImplementations)); |
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.
PR #919 attempts to optimize the amount of memory traffic going on in an effort to speed up things like mobile applications, where allocations cost time and battery. Having to allocate a whole new list every time here seems like it might counteract some of those optimizations. We might have to balance the lock contention improvement with the memory usage/optimization improvements.
I got a chance to look at this and, just eyeballing it, I think the |
…e resolution. Change extracted from PR #953. Added some benchmarks for concurrent resolution.
I have taken the |
@alexmg you can not just take changes in Please consider reverting your partial changes or take full changes. |
Hi @avtc. Your response does come a little late as the release has been pushed to NuGet, but not too late for another release if required. I guess you must have missed the comment from @tillig and I took the lack of response to mean you had no concerns.
In the concurrency tests I created I did not see any |
@alexmg you are right, i missed that point. Maybe only in case registrations will be added after Also, i would suggest to make |
@avtc I actually went and had another look at the |
I have released |
Nolock solution for
TryGetRegistration
,IsRegistered
,RegistrationsFor
. Issues: #941, #906For case when
ServiceRegistrationInfo
is already exists andIsInitialized
, i.e. after service was Resolved once.There can be little memory overhead during initialization, but that is a small price for allowing it to work in multi-core high load environment.