Skip to content
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

TryAddWithoutValidation for multiple values could be more efficient #102845

Merged
merged 5 commits into from
Jun 10, 2024

Conversation

pedrobsaila
Copy link
Contributor

@pedrobsaila pedrobsaila commented May 29, 2024

Fixes #64049
perfomance test dotnet/performance#4240

BenchmarkDotNet v0.13.13-nightly.20240311.145, Windows 11 (10.0.22631.3593/23H2/2023Update/SunValley3)
12th Gen Intel Core i7-12700H, 1 CPU, 20 logical and 14 physical cores
.NET SDK 9.0.100-preview.4.24267.66
  [Host]     : .NET 9.0.0 (9.0.24.26619), X64 RyuJIT AVX2
  Job-RIQMYG : .NET 9.0.0 (42.42.42.42424), X64 RyuJIT AVX2
  Job-UYKONU : .NET 9.0.0 (42.42.42.42424), X64 RyuJIT AVX2

PowerPlanMode=00000000-0000-0000-0000-000000000000  IterationTime=250ms  MaxIterationCount=20  
MinIterationCount=15  WarmupCount=1  
Method Toolchain data Mean Error Ratio Allocated Alloc Ratio
AddHeaders pr Array 45.91 ns 1.350 ns 0.54 336 B 0.69
AddHeaders main Array 84.59 ns 1.230 ns 1.00 488 B 1.00
AddHeaders pr Hashset 86.72 ns 1.129 ns 0.97 496 B 1.00
AddHeaders main Hashset 89.18 ns 1.356 ns 1.00 496 B 1.00
AddHeaders pr List 45.95 ns 0.730 ns 0.54 336 B 0.68
AddHeaders main List 85.28 ns 0.809 ns 1.00 496 B 1.00

@dotnet-policy-service dotnet-policy-service bot added the community-contribution Indicates that the PR has been added by a community member label May 29, 2024
Copy link
Member

@MihaZupan MihaZupan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks.

@dotnet/ncl could I get a secondary pair of eyes on this one given it's based on my gist from the original issue https://gist.github.com/MihaZupan/800df7a324a66a8e814c3ec91f3d39b0

@MihaZupan MihaZupan added this to the 9.0.0 milestone May 29, 2024
Copy link
Member

@rzikm rzikm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM if CI is green (modulo existing comments from MihaZupan). Maybe just add a few comments for those who are not that familiar with the codebase.

@pedrobsaila
Copy link
Contributor Author

pedrobsaila commented May 31, 2024

New results after adjusting performance test and TryAddWithoutValidation method :

Toolchain data Mean Error StdDev Median Min Max Ratio Gen0 Allocated Alloc Ratio
PR Array 34.59 ns 0.360 ns 0.300 ns 34.54 ns 34.13 ns 35.23 ns 0.47 0.0102 128 B 0.46
master Array 73.25 ns 0.744 ns 0.696 ns 73.29 ns 72.11 ns 74.30 ns 1.00 0.0222 280 B 1.00
PR Hashset 73.48 ns 0.945 ns 0.884 ns 73.63 ns 72.30 ns 75.03 ns 0.95 0.0227 288 B 1.00
master Hashset 77.19 ns 0.902 ns 0.799 ns 77.15 ns 76.24 ns 79.22 ns 1.00 0.0227 288 B 1.00
PR List 36.77 ns 0.477 ns 0.446 ns 36.84 ns 35.91 ns 37.65 ns 0.48 0.0101 128 B 0.44
master List 76.21 ns 0.468 ns 0.438 ns 76.24 ns 75.48 ns 77.11 ns 1.00 0.0228 288 B 1.00

Copy link
Member

@MihaZupan MihaZupan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I imagine that the most common scenario for this API is a string[] with 1 value for a header that doesn't yet exist in the collection.
In that case, we can save an allocation from avoiding the boxing of the IEnumerator.

I'm not as convinced optimizing cases like an enumerable that isn't an IList is worth the extra maintainability cost in practice.

@pedrobsaila
Copy link
Contributor Author

pedrobsaila commented May 31, 2024

The new result after the last changes (it seems the slow path underperformed by rewriting it as foreach loop that calls unitary TryAddWithoutValidation) :

Toolchain data Mean Error StdDev Median Min Max Ratio RatioSD Gen0 Allocated Alloc Ratio
PR Array 52.23 ns 0.452 ns 0.353 ns 52.18 ns 51.69 ns 52.84 ns 0.68 0.01 0.0100 128 B 0.46
master Array 76.35 ns 1.302 ns 1.218 ns 76.41 ns 74.83 ns 79.53 ns 1.00 0.02 0.0222 280 B 1.00
PR Hashset 84.33 ns 3.491 ns 3.880 ns 82.85 ns 80.04 ns 92.59 ns 1.10 0.05 0.0229 288 B 1.00
master Hashset 76.53 ns 0.741 ns 0.693 ns 76.30 ns 75.67 ns 77.71 ns 1.00 0.01 0.0229 288 B 1.00
PR List 36.12 ns 0.289 ns 0.271 ns 36.05 ns 35.78 ns 36.68 ns 0.47 0.01 0.0102 128 B 0.44
master List 76.49 ns 0.829 ns 0.692 ns 76.42 ns 75.49 ns 78.12 ns 1.00 0.01 0.0229 288 B 1.00

@pedrobsaila
Copy link
Contributor Author

New benchmark results :

Toolchain data Mean Error StdDev Median Min Max Ratio RatioSD Gen0 Allocated Alloc Ratio
PR Array 51.95 ns 0.638 ns 0.498 ns 52.16 ns 51.05 ns 52.46 ns 0.68 0.01 0.0101 128 B 0.46
master Array 75.87 ns 0.727 ns 0.680 ns 75.67 ns 74.51 ns 77.00 ns 1.00 0.01 0.0223 280 B 1.00
PR Hashset 80.39 ns 0.579 ns 0.513 ns 80.30 ns 79.74 ns 81.31 ns 1.03 0.02 0.0227 288 B 1.00
master Hashset 77.68 ns 1.145 ns 1.071 ns 77.89 ns 75.62 ns 79.58 ns 1.00 0.02 0.0227 288 B 1.00
PR List 36.47 ns 0.373 ns 0.349 ns 36.43 ns 35.98 ns 37.20 ns 0.47 0.01 0.0101 128 B 0.44
master List 77.63 ns 1.135 ns 1.006 ns 77.47 ns 75.94 ns 79.15 ns 1.00 0.02 0.0227 288 B 1.00

@MihaZupan
Copy link
Member

/azp run runtime

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Net.Http community-contribution Indicates that the PR has been added by a community member
Projects
None yet
Development

Successfully merging this pull request may close these issues.

TryAddWithoutValidation for multiple values could be more efficient
3 participants