summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Toub <stoub@microsoft.com>2019-01-21 16:20:18 -0500
committerGitHub <noreply@github.com>2019-01-21 16:20:18 -0500
commit401e931714e9b0890aaaa047710d0eb582bb8722 (patch)
treeaaa793feae354a85a4d3a707188f4e872e5726be
parenta5c5feb8939ae6ae10d9d2b7f2bc8d43ed99bc38 (diff)
downloadcoreclr-401e931714e9b0890aaaa047710d0eb582bb8722.tar.gz
coreclr-401e931714e9b0890aaaa047710d0eb582bb8722.tar.bz2
coreclr-401e931714e9b0890aaaa047710d0eb582bb8722.zip
Avoid intermediate strings in some StringBuilder formatting (#22111)
* Avoid intermediate strings in some StringBuilder formatting Several appends to string builders are first creating strings and then appending those strings, and they're not using the existing Append(primitive) overloads because they want to customize the format string or provider as part of appending the value. This fixes a few of those cases, using another internal AppendSpanFormattable overload on StringBuilder. * Address PR feedback
-rw-r--r--src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormat.cs11
-rw-r--r--src/System.Private.CoreLib/shared/System/Globalization/TimeSpanFormat.cs4
-rw-r--r--src/System.Private.CoreLib/shared/System/Text/StringBuilder.cs11
-rw-r--r--src/System.Private.CoreLib/shared/System/TimeZoneInfo.StringSerializer.cs20
4 files changed, 30 insertions, 16 deletions
diff --git a/src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormat.cs b/src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormat.cs
index 61143fecfd..b105324a6b 100644
--- a/src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormat.cs
+++ b/src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormat.cs
@@ -509,7 +509,7 @@ namespace System
fraction = fraction / (long)Math.Pow(10, 7 - tokenLen);
if (ch == 'f')
{
- result.Append(((int)fraction).ToString(fixedNumberFormats[tokenLen - 1], CultureInfo.InvariantCulture));
+ result.AppendSpanFormattable((int)fraction, fixedNumberFormats[tokenLen - 1], CultureInfo.InvariantCulture);
}
else
{
@@ -528,7 +528,7 @@ namespace System
}
if (effectiveDigits > 0)
{
- result.Append(((int)fraction).ToString(fixedNumberFormats[effectiveDigits - 1], CultureInfo.InvariantCulture));
+ result.AppendSpanFormattable((int)fraction, fixedNumberFormats[effectiveDigits - 1], CultureInfo.InvariantCulture);
}
else
{
@@ -679,10 +679,13 @@ namespace System
{
FormatDigits(result, year % 100, tokenLen);
}
+ else if (tokenLen <= 16) // FormatDigits has an implicit 16-digit limit
+ {
+ FormatDigits(result, year, tokenLen, overrideLengthLimit: true);
+ }
else
{
- string fmtPattern = "D" + tokenLen.ToString();
- result.Append(year.ToString(fmtPattern, CultureInfo.InvariantCulture));
+ result.Append(year.ToString("D" + tokenLen.ToString(), CultureInfo.InvariantCulture));
}
}
bTimeOnly = false;
diff --git a/src/System.Private.CoreLib/shared/System/Globalization/TimeSpanFormat.cs b/src/System.Private.CoreLib/shared/System/Globalization/TimeSpanFormat.cs
index 5e553d56b4..ccb42ad87c 100644
--- a/src/System.Private.CoreLib/shared/System/Globalization/TimeSpanFormat.cs
+++ b/src/System.Private.CoreLib/shared/System/Globalization/TimeSpanFormat.cs
@@ -400,7 +400,7 @@ namespace System.Globalization
tmp = fraction;
tmp /= TimeSpanParse.Pow10(DateTimeFormat.MaxSecondsFractionDigits - tokenLen);
- result.Append((tmp).ToString(DateTimeFormat.fixedNumberFormats[tokenLen - 1], CultureInfo.InvariantCulture));
+ result.AppendSpanFormattable(tmp, DateTimeFormat.fixedNumberFormats[tokenLen - 1], CultureInfo.InvariantCulture);
break;
case 'F':
//
@@ -429,7 +429,7 @@ namespace System.Globalization
}
if (effectiveDigits > 0)
{
- result.Append((tmp).ToString(DateTimeFormat.fixedNumberFormats[effectiveDigits - 1], CultureInfo.InvariantCulture));
+ result.AppendSpanFormattable(tmp, DateTimeFormat.fixedNumberFormats[effectiveDigits - 1], CultureInfo.InvariantCulture);
}
break;
case 'd':
diff --git a/src/System.Private.CoreLib/shared/System/Text/StringBuilder.cs b/src/System.Private.CoreLib/shared/System/Text/StringBuilder.cs
index 75b7ed6b4a..cd88d2199d 100644
--- a/src/System.Private.CoreLib/shared/System/Text/StringBuilder.cs
+++ b/src/System.Private.CoreLib/shared/System/Text/StringBuilder.cs
@@ -1179,6 +1179,17 @@ namespace System.Text
return Append(value.ToString());
}
+ internal StringBuilder AppendSpanFormattable<T>(T value, string format, IFormatProvider provider) where T : ISpanFormattable, IFormattable
+ {
+ if (value.TryFormat(RemainingCurrentChunk, out int charsWritten, format, provider))
+ {
+ m_ChunkLength += charsWritten;
+ return this;
+ }
+
+ return Append(value.ToString(format, provider));
+ }
+
public StringBuilder Append(object value) => (value == null) ? this : Append(value.ToString());
public StringBuilder Append(char[] value)
diff --git a/src/System.Private.CoreLib/shared/System/TimeZoneInfo.StringSerializer.cs b/src/System.Private.CoreLib/shared/System/TimeZoneInfo.StringSerializer.cs
index e3e9ddbf58..a0b92eaac9 100644
--- a/src/System.Private.CoreLib/shared/System/TimeZoneInfo.StringSerializer.cs
+++ b/src/System.Private.CoreLib/shared/System/TimeZoneInfo.StringSerializer.cs
@@ -49,7 +49,7 @@ namespace System
//
SerializeSubstitute(zone.Id, serializedText);
serializedText.Append(Sep);
- serializedText.Append(zone.BaseUtcOffset.TotalMinutes.ToString(CultureInfo.InvariantCulture));
+ serializedText.AppendSpanFormattable(zone.BaseUtcOffset.TotalMinutes, format: default, CultureInfo.InvariantCulture);
serializedText.Append(Sep);
SerializeSubstitute(zone.DisplayName, serializedText);
serializedText.Append(Sep);
@@ -62,11 +62,11 @@ namespace System
foreach (AdjustmentRule rule in rules)
{
serializedText.Append(Lhs);
- serializedText.Append(rule.DateStart.ToString(DateTimeFormat, DateTimeFormatInfo.InvariantInfo));
+ serializedText.AppendSpanFormattable(rule.DateStart, DateTimeFormat, DateTimeFormatInfo.InvariantInfo);
serializedText.Append(Sep);
- serializedText.Append(rule.DateEnd.ToString(DateTimeFormat, DateTimeFormatInfo.InvariantInfo));
+ serializedText.AppendSpanFormattable(rule.DateEnd, DateTimeFormat, DateTimeFormatInfo.InvariantInfo);
serializedText.Append(Sep);
- serializedText.Append(rule.DaylightDelta.TotalMinutes.ToString(CultureInfo.InvariantCulture));
+ serializedText.AppendSpanFormattable(rule.DaylightDelta.TotalMinutes, format: default, CultureInfo.InvariantCulture);
serializedText.Append(Sep);
// serialize the TransitionTime's
SerializeTransitionTime(rule.DaylightTransitionStart, serializedText);
@@ -76,7 +76,7 @@ namespace System
if (rule.BaseUtcOffsetDelta != TimeSpan.Zero)
{
// Serialize it only when BaseUtcOffsetDelta has a value to reduce the impact of adding rule.BaseUtcOffsetDelta
- serializedText.Append(rule.BaseUtcOffsetDelta.TotalMinutes.ToString(CultureInfo.InvariantCulture));
+ serializedText.AppendSpanFormattable(rule.BaseUtcOffsetDelta.TotalMinutes, format: default, CultureInfo.InvariantCulture);
serializedText.Append(Sep);
}
if (rule.NoDaylightTransitions)
@@ -155,20 +155,20 @@ namespace System
serializedText.Append(Lhs);
serializedText.Append(time.IsFixedDateRule ? '1' : '0');
serializedText.Append(Sep);
- serializedText.Append(time.TimeOfDay.ToString(TimeOfDayFormat, DateTimeFormatInfo.InvariantInfo));
+ serializedText.AppendSpanFormattable(time.TimeOfDay, TimeOfDayFormat, DateTimeFormatInfo.InvariantInfo);
serializedText.Append(Sep);
- serializedText.Append(time.Month.ToString(CultureInfo.InvariantCulture));
+ serializedText.AppendSpanFormattable(time.Month, format: default, CultureInfo.InvariantCulture);
serializedText.Append(Sep);
if (time.IsFixedDateRule)
{
- serializedText.Append(time.Day.ToString(CultureInfo.InvariantCulture));
+ serializedText.AppendSpanFormattable(time.Day, format: default, CultureInfo.InvariantCulture);
serializedText.Append(Sep);
}
else
{
- serializedText.Append(time.Week.ToString(CultureInfo.InvariantCulture));
+ serializedText.AppendSpanFormattable(time.Week, format: default, CultureInfo.InvariantCulture);
serializedText.Append(Sep);
- serializedText.Append(((int)time.DayOfWeek).ToString(CultureInfo.InvariantCulture));
+ serializedText.AppendSpanFormattable((int)time.DayOfWeek, format: default, CultureInfo.InvariantCulture);
serializedText.Append(Sep);
}
serializedText.Append(Rhs);