Improve throughput of TimeSpan.ToString/TryFormat with "g"/"G" (dotnet/coreclr#19051)
authorStephen Toub <stoub@microsoft.com>
Fri, 20 Jul 2018 10:56:57 +0000 (03:56 -0700)
committerGitHub <noreply@github.com>
Fri, 20 Jul 2018 10:56:57 +0000 (03:56 -0700)
commitbb91858e795cd2f2ea707d6fc8aed1d7ffe1845e
treee6cb6042776254e24ba4afc491036db1e0539365
parente566a119fbae12d9c3f58aa4a2e753d776079faf
Improve throughput of TimeSpan.ToString/TryFormat with "g"/"G" (dotnet/coreclr#19051)

* Improve throughput of TimeSpan.ToString/TryFormat with "g"/"G"

TimeSpan has three standard formats: "c", "g", and "G".  Yesterday I updated its implementation with throughput improvements for "c" (the default) based on porting the design from Utf8Formatter; this PR does so for "g"/"G".

Initially I wasn't going to handle "g"/"G" as they factor in culture (Utf8Formatter doesn't), but even with accessing the current culture there are still significant wins to be had.  I was also going to keep the "c" and "g"/"G" implementations separate, to avoid bogging down the default "c" formatting with additional conditions needed to support "g"/"G", but the overhead incurred for that turns out to be minimal enough that it's worth keeping one implementation rather than two mostly-similar ones... the impact on "c" is mostly within noise.

This PR makes a significant throughput improvement for "g"/"G" formatting.  It also removes several unnecessary allocations, such that TryFormat with "g"/"G" is now allocation-free (and ToString just allocates the asked-for string).

* Address PR feedback

Commit migrated from https://github.com/dotnet/coreclr/commit/6860d110a843e882357d82d2a72205343339b11b
src/libraries/System.Private.CoreLib/src/System/Buffers/Text/FormattingHelpers.CountDigits.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeFormatInfo.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/TimeSpanFormat.cs