Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Improve Enum.ToString perf for [Flags] enums #21254

Merged
merged 1 commit into from
Nov 29, 2018

Conversation

stephentoub
Copy link
Member

Two main changes:

  • Rather than using a StringBuilder to insert the strings for all of the constituent values, we track the constituent values in a span, summing the expected length, and then new up a string and copy the results directly into it.
  • When there's a single value that matches the supplied value, we just return the cached string rather than allocating a new one.
Method Value Before Time (ns) After Time (ns) Before Alloc (b) After Alloc (b) Time Improvement Alloc Improvement
FlagsToString 2147483647 422.54 103.70 96 96 4.07x 1.00x
FlagsToString Eighth 85.88 28.54 64 24 3.01x 2.67x
FlagsToString Eleventh, Twelth, Sixth, Seventh, Eighth 385.98 83.00 128 128 4.65x 1.00x
FlagsToString Fifth, Seventh 139.75 58.62 80 80 2.38x 1.00x
FlagsToString First 85.57 34.03 56 24 2.51x 2.33x
FlagsToString None 53.49 26.92 24 24 1.99x 1.00x
FlagsToString Twelth 90.19 29.13 64 24 3.10x 2.67x

cc: @jkotas, @ahsonkhan, @GrabYourPitchforks, @joperezr

Two main changes:
- Rather than using a StringBuilder to insert the strings for all of the consistuent values, we track the constituent values in a span, summing the expected length, and then new up a string and copy the results directly into it.
- When there's a single value that matches the supplied value, we just return the cached string rather than allocating a new one.
Copy link
Member

@jkotas jkotas left a comment

Choose a reason for hiding this comment

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

Nice

resultSpan[1] = ' ';
resultSpan = resultSpan.Slice(2);

name = names[foundItems[foundItemsCount]];

Choose a reason for hiding this comment

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

nit: This is essentially iteration over all the foundItems, correct? Would writing it as a regular for loop increase readability?

for (int i = foundItemsCount - 1; i >= 0; i--)
{
   ...

   int index = foundItems[i];
   name = names[index];

   ...
}

@jkotas jkotas merged commit effe7ca into dotnet:master Nov 29, 2018
@stephentoub stephentoub deleted the enumflagstostring branch March 21, 2019 18:38
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
Two main changes:
- Rather than using a StringBuilder to insert the strings for all of the consistuent values, we track the constituent values in a span, summing the expected length, and then new up a string and copy the results directly into it.
- When there's a single value that matches the supplied value, we just return the cached string rather than allocating a new one.

Commit migrated from dotnet/coreclr@effe7ca
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants