-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Improved performance and memory consumption #9080
base: main
Are you sure you want to change the base?
Conversation
src/Orleans.Runtime/MembershipService/ClusterMembershipService.cs
Outdated
Show resolved
Hide resolved
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.
Generally, looks good to me, thank you! There are a few places where changes need to be made for correctness. These kinds of PRs are best split up into smaller PRs (eg, one per type of change), and if you use a tool to assist with the changes, please let us know and tell us where you made interventions, since that helps with reviewing.
Hello @ReubenBond, I highly appreciate your feedback! I've resolved your comments and created #9082 to handle the problem with undisposed objects. I will take your advice into consideration and follow it in the future. Looking forward for future cooperation. Thank you! |
Out of curiosity, if we had replaced the following line
with
Would we get the same optimization as with |
Hello @tchelidze, When comparing in-memory collections, the main differences between
foreach (TSource sourceItem in sourceCollection)
{
if (predicate(sourceItem))
return sourceItem;
}
return default(TSource);
for (int index = 0; index < sourceCollection.Length; ++index)
{
if (predicate(sourceCollection[index]))
return sourceCollection[index];
}
return default(TSource); These different approaches show next benchmark results (with warmup): BenchmarkDotNet v0.13.10, Windows 11 (10.0.22631.3958/23H2/2023Update/SunValley3)
Intel Core i7-10510U CPU 1.80GHz, 1 CPU, 8 logical and 4 physical cores
.NET SDK 8.0.400-preview.0.24324.5
[Host] : .NET 6.0.30 (6.0.3024.21525), X64 RyuJIT AVX2 [AttachedDebugger]
DefaultJob : .NET 6.0.30 (6.0.3024.21525), X64 RyuJIT AVX2
| Method | Mean | Error | StdDev | Median | Gen0 | Allocated |
|------------------- |------------:|----------:|-----------:|------------:|-------:|----------:|
| FirstOrDefault10 | 78.80 ns | 1.511 ns | 2.983 ns | 78.22 ns | 0.0076 | 32 B |
| Find10 | 17.66 ns | 0.400 ns | 1.103 ns | 17.18 ns | - | - |
| FirstOrDefault100 | 554.24 ns | 9.811 ns | 18.427 ns | 549.59 ns | 0.0076 | 32 B |
| Find100 | 138.38 ns | 3.218 ns | 9.128 ns | 134.32 ns | - | - |
| FirstOrDefault1000 | 4,515.42 ns | 65.601 ns | 114.895 ns | 4,502.85 ns | 0.0076 | 32 B |
| Find1000 | 1,221.08 ns | 23.956 ns | 24.601 ns | 1,211.59 ns | - | - | From a performance perspective, the method you choose has minimal impact on small collections. However, as the size of the collection increases, |
- Replaced LINQ methods with more efficient alternatives. - Ensured proper disposal of `CancellationTokenSource` instances. - Optimized string handling by using `StringBuilder` instead of string concatenation.
…cs`, `StatelessWorkerGrainContext.cs`, `ClusterMembershipService.cs`, and `Silo.cs`
Thanks for the comprehensive explanation @ivanvyd |
@ivanvyd I believe this is no longer the case as of .NET 9 (to be released in ~2 weeks) due to a PR on the dotnet runtime repo (merged on July 22nd) optimizing these specific cases. Most, if not all, of the LINQ extensions methods using a predicate to filter items are now span based, which will no longer allocate any memory on the heap when performing the loop. |
CancellationTokenSource
instances.StringBuilder
instead of string concatenation.Microsoft Reviewers: Open in CodeFlow