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

Optimize performance of GetHashCode for ContentType comparers, remove allocs #9723

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

h3xds1nz
Copy link
Contributor

@h3xds1nz h3xds1nz commented Sep 5, 2024

Description

Removes allocations for ContentType's WeakComparer and StrongComparer (which are used in the related dictionaries).

  • We will use StringComparer.OrdinalIgnoreCase.GetHashCode(src) instead of src.ToUpperInvariant.GetHashCode() as that creates a new string everytime just so we can retrieve HashCode out of it.
  • This will reduce allocations to zero and also save about 40ns (depending on length, it scales up) per invocation while preserving functionality.

Benchmarks

Method Mean [ns] Error [ns] StdDev [ns] Gen0 Code Size [B] Allocated [B]
Original 34.736 ns 0.2199 ns 0.2057 ns 0.0038 392 B 64 B
PR_EDIT 8.620 ns 0.0279 ns 0.0247 ns - 330 B -
Method Mean [ns] Error [ns] StdDev [ns] Gen0 Code Size [B] Allocated [B]
Original 70.84 ns 1.404 ns 1.379 ns 0.0110 394 B 184 B
PR_EDIT 41.27 ns 0.127 ns 0.113 ns - 316 B -
Method Mean [ns] Error [ns] StdDev [ns] Gen0 Code Size [B] Allocated [B]
Original 183.5 ns 2.76 ns 2.58 ns 0.0310 394 B 520 B
PR_EDIT 132.4 ns 0.40 ns 0.35 ns - 333 B -

Benchmark code

//First invocation
return "aBCD".ToUpperInvariant().GetHashCode() ^ "xDDAH".ToUpperInvariant().GetHashCode();
return StringComparer.OrdinalIgnoreCase.GetHashCode("aBCD") ^ StringComparer.OrdinalIgnoreCase.GetHashCode("xDDAH");

//Second invocation
return "aBCDnowimagineifthisisLongstring".ToUpperInvariant().GetHashCode() ^ "xDDAHaBCDnowimagineifthisisLongstring".ToUpperInvariant().GetHashCode();
return StringComparer.OrdinalIgnoreCase.GetHashCode("aBCDnowimagineifthisisLongstring") ^ StringComparer.OrdinalIgnoreCase.GetHashCode("xDDAHaBCDnowimagineifthisisLongstring");

//Third invocation
return "aBCDnowimagineifthisisLongstringWeNeedthistobewaylongeeeeeeerrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr".ToUpperInvariant().GetHashCode() ^
"xDDAHaBCDnowimagineifthisisLongstringaBCDnowimagineifthisisLongstringWeNeedthistobewaylongeeeeeeerrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr".ToUpperInvariant().GetHashCode();
return StringComparer.OrdinalIgnoreCase.GetHashCode("aBCDnowimagineifthisisLongstringWeNeedthistobewaylongeeeeeeerrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr") ^ 
StringComparer.OrdinalIgnoreCase.GetHashCode("xDDAHaBCDnowimagineifthisisLongstringaBCDnowimagineifthisisLongstringWeNeedthistobewaylongeeeeeeerrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr");

Customer Impact

Increased performance, including start-up performance, decreased allocations.

Regression

No.

Testing

Local build, assert test:

int hashCode1 = "áBCD".ToUpperInvariant().GetHashCode() ^ "xDDAH".ToUpperInvariant().GetHashCode();
int hashCode2 = StringComparer.OrdinalIgnoreCase.GetHashCode("ÁBCD") ^ StringComparer.OrdinalIgnoreCase.GetHashCode("xDDAH");
Assert.AreEqual(hashCode1, hashCode2);

Risk

Low.

Microsoft Reviewers: Open in CodeFlow

@h3xds1nz h3xds1nz requested review from a team as code owners September 5, 2024 19:27
@dotnet-policy-service dotnet-policy-service bot added PR metadata: Label to tag PRs, to facilitate with triage Community Contribution A label for all community Contributions labels Sep 5, 2024
@h3xds1nz
Copy link
Contributor Author

h3xds1nz commented Sep 5, 2024

CI failure caused by #9632 requesting System.Drawing.Common from .NET 8 (v8.0.8).

@harshit7962
Copy link
Member

/azp run

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Community Contribution A label for all community Contributions PR metadata: Label to tag PRs, to facilitate with triage
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants