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

Improve DateTime.ParseExact perf for invariant culture #82877

Merged
merged 3 commits into from Mar 3, 2023

Conversation

stephentoub
Copy link
Member

Speed up the handling of ddd, dddd, MMM, and MMMM parts of a date time format string when using the invariant culture, which is very commonly used in parsing. Today, when one of these is encountered, the relevant array of comparison strings is retrieved from the DateTimeFormatInfo, and each is compared as a prefix against the current position in the input, using a linguistic ignore-case comparison. But for the invariant culture, we don't need to consult any arrays, and can do the comparison much more quickly. These parts dominate the processing of a format like that for RFC1123.

Method Toolchain Mean Error StdDev Ratio
ParseExact \main\corerun.exe 997.4 ns 19.97 ns 17.70 ns 1.00
ParseExact \pr\corerun.exe 359.9 ns 2.99 ns 2.65 ns 0.36
const string Format = "ddd, dd MMM yyyy HH':'mm':'ss 'GMT'";

private string _s = new DateTime(1955, 11, 5, 6, 0, 0, DateTimeKind.Utc).ToString(Format, CultureInfo.InvariantCulture);

[Benchmark]
public void ParseExact() => DateTimeOffset.ParseExact(_s, Format, CultureInfo.InvariantCulture, DateTimeStyles.AllowInnerWhite | DateTimeStyles.AssumeUniversal);

@stephentoub stephentoub added this to the 8.0.0 milestone Mar 2, 2023
@ghost ghost assigned stephentoub Mar 2, 2023
@ghost
Copy link

ghost commented Mar 2, 2023

Tagging subscribers to this area: @dotnet/area-system-globalization
See info in area-owners.md if you want to be subscribed.

Issue Details

Speed up the handling of ddd, dddd, MMM, and MMMM parts of a date time format string when using the invariant culture, which is very commonly used in parsing. Today, when one of these is encountered, the relevant array of comparison strings is retrieved from the DateTimeFormatInfo, and each is compared as a prefix against the current position in the input, using a linguistic ignore-case comparison. But for the invariant culture, we don't need to consult any arrays, and can do the comparison much more quickly. These parts dominate the processing of a format like that for RFC1123.

Method Toolchain Mean Error StdDev Ratio
ParseExact \main\corerun.exe 997.4 ns 19.97 ns 17.70 ns 1.00
ParseExact \pr\corerun.exe 359.9 ns 2.99 ns 2.65 ns 0.36
const string Format = "ddd, dd MMM yyyy HH':'mm':'ss 'GMT'";

private string _s = new DateTime(1955, 11, 5, 6, 0, 0, DateTimeKind.Utc).ToString(Format, CultureInfo.InvariantCulture);

[Benchmark]
public void ParseExact() => DateTimeOffset.ParseExact(_s, Format, CultureInfo.InvariantCulture, DateTimeStyles.AllowInnerWhite | DateTimeStyles.AssumeUniversal);
Author: stephentoub
Assignees: -
Labels:

area-System.Globalization, tenet-performance

Milestone: 8.0.0

Speed up the handling of ddd, dddd, MMM, and MMMM parts of a date time format string when using the invariant culture, which is very commonly used in parsing.  Today, when one of these is encountered, the relevant array of comparison strings is retrieved from the DateTimeFormatInfo, and each is compared as a prefix against the current position in the input, using a linguistic ignore-case comparison.  But for the invariant culture, we don't need to consult any arrays, and can do the comparison much more quickly.  These parts dominate the processing of a format like that for RFC1123.
}
else
{
// Scan the month names (note that some calendars has 13 months) and find
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// Scan the month names (note that some calendars has 13 months) and find
// Scan the month names (note that some calendars have 13 months) and find

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks. These are both pre-existing. If I have to restart CI for some reason, I'll take the comment fixes.

{
// Scan the month names (note that some calendars has 13 months) and find
// the matching month name which has the max string length.
// We need to do this because some cultures (e.g. "cs-CZ") which have
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// We need to do this because some cultures (e.g. "cs-CZ") which have
// We need to do this because some cultures (e.g. "cs-CZ") have

@stephentoub
Copy link
Member Author

Failures are known

@stephentoub stephentoub merged commit eb6b81c into dotnet:main Mar 3, 2023
161 of 166 checks passed
@stephentoub stephentoub deleted the dtinvariant branch March 3, 2023 02:46
@dotnet dotnet locked as resolved and limited conversation to collaborators Apr 2, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants