-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Reduce contention for Datacontract Serialization #70668
Reduce contention for Datacontract Serialization #70668
Conversation
…ing DataContractSerializer
...es/System.Private.DataContractSerialization/src/System/Runtime/Serialization/DataContract.cs
Outdated
Show resolved
Hide resolved
Commenting reply here as well since it is hidden when resolved. I did a small benchmarks (single threaded), which just invokes GetId for different keys with almost no adds just to measure overhead for the non-contented case and settled for using concurrent dictionary + lazy. BenchmarkDotNet=v0.13.1, OS=Windows 10.0.22000
AMD Ryzen 7 5800X, 1 CPU, 16 logical and 8 physical cores
.NET SDK=7.0.100-preview.4.22252.9
[Host] : .NET 6.0.5 (6.0.522.21309), X64 RyuJIT
DefaultJob : .NET 6.0.5 (6.0.522.21309), X64 RyuJIT
Update: I switched to use RuntimeTypeHandle as key in order to make the code simpler (since there is no ThreadStatic storage required to cache type handles) which also had the benefit of better performance than original code. In original code GetBuiltInDataContract took 9,8% of time GetId took 0.5% of time. |
We have a very large PR in the works trying to reconcile the strange port of DCS that has been in .Net Core with the more complete version in .Net 4.8. (#71752). In doing this reconciliation, I believe this issue is also addressed - in a similar but not exactly the same manner. After that PR goes through though, you should see performance improvement here. If not, please reopen the issue. |
@StephenMolloy do you have time frame for your large pr, Is there any chance of this getting reviewed in time to make it possible for a merge before the net7 cut-off date at August 15 ? I did a quick test if your pr and it only improves performance marginally so I think it still makes sense to improve the 2 methods that are changed here. |
As mentioned earlier, a similar approach on this particular issue has been brought back from .Net 4.8 in our mega reconciliation of 7.0 with 4.8. #71752 has been checked in now. Hopefully you see this show up in your performance testing of RC1. |
Making profiling/stress testing my rewrite of OpenRiaServices from WCF to aspnet core I identified a bottleneck in the datacontract serializer.
I detected some contention for an API returning around 20 000 objects of a fairly simple type with a datacontract surrogate which looks the same.
This fix is made in 2 steps,
Loadtesting was done from local machine so the load testing (Netling/Westwind Web Surge) also consume resources
Initially GetBuiltInDataContract was the source of contention.
Contention time for 20s run:
When fixing that most contention seemed to move to GetId:
Contention time for 20s run after first commit:
Other possible solutions / comments
I decided to keep current logic in order to keep the change small and not affect startup/first access performance to much,
Numbers
On 16 AMD 5800X
8 thead loading
16 threads loading
From left to right:
net7 preview 4 + second commits(100% cpu load including load generation)* net7 preview 4 + 4th commit (lazy + changed key) *
1 or 2 threads loaded
No significant difference between the versions to draw any conclusions.update August: performance seems to be better even with no or little concurrency.
Other