summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Toub <stoub@microsoft.com>2019-01-21 21:20:18 (GMT)
committerGitHub <noreply@github.com>2019-01-21 21:20:18 (GMT)
commit401e931714e9b0890aaaa047710d0eb582bb8722 (patch)
treeaaa793feae354a85a4d3a707188f4e872e5726be
parenta5c5feb8939ae6ae10d9d2b7f2bc8d43ed99bc38 (diff)
downloadcoreclr-401e931714e9b0890aaaa047710d0eb582bb8722.zip
coreclr-401e931714e9b0890aaaa047710d0eb582bb8722.tar.gz
coreclr-401e931714e9b0890aaaa047710d0eb582bb8722.tar.bz2
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 61143fe..b105324 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 5e553d5..ccb42ad 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 75b7ed6..cd88d21 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 e3e9ddb..a0b92ea 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);