diff options
author | Jeremy Kuhne <jeremy.kuhne@microsoft.com> | 2018-08-05 23:22:57 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-08-05 23:22:57 -0700 |
commit | ac8f8e52c49b0ffa712d68730a41883d281bea01 (patch) | |
tree | 1a44dbcc7bf1b93e710a544a4e720681e2387dbc | |
parent | 29b59d54f3816886742cb9aaff6b96ee0625264c (diff) | |
download | coreclr-ac8f8e52c49b0ffa712d68730a41883d281bea01.tar.gz coreclr-ac8f8e52c49b0ffa712d68730a41883d281bea01.tar.bz2 coreclr-ac8f8e52c49b0ffa712d68730a41883d281bea01.zip |
Improve StreamWriter format perf (#19235)
* Improve StreamWriter format perf
Override the format overloads for TextWriter and skip the extra string allocation for the formatted string by using StringBuilder directly, copying straight to the output buffer.
Improves performance roughtly 10% and cuts allocations by 10x and up (formatting a string into a string goes to *zero* allocations).
* Fix copy/paste slipup- test added to CoreFX PR
-rw-r--r-- | src/System.Private.CoreLib/shared/System/IO/StreamWriter.cs | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/src/System.Private.CoreLib/shared/System/IO/StreamWriter.cs b/src/System.Private.CoreLib/shared/System/IO/StreamWriter.cs index b510b6b287..8d94ac60b9 100644 --- a/src/System.Private.CoreLib/shared/System/IO/StreamWriter.cs +++ b/src/System.Private.CoreLib/shared/System/IO/StreamWriter.cs @@ -476,6 +476,123 @@ namespace System.IO } } + private void WriteFormatHelper(string format, ParamsArray args, bool appendNewLine) + { + StringBuilder sb = + StringBuilderCache.Acquire(format.Length + args.Length * 8) + .AppendFormatHelper(null, format, args); + + StringBuilder.ChunkEnumerator chunks = sb.GetChunks(); + + bool more = chunks.MoveNext(); + while (more) + { + ReadOnlySpan<char> current = chunks.Current.Span; + more = chunks.MoveNext(); + + // If final chunk, include the newline if needed + WriteSpan(current, appendNewLine: more ? false : appendNewLine); + } + + StringBuilderCache.Release(sb); + } + + public override void Write(string format, object arg0) + { + if (GetType() == typeof(StreamWriter)) + { + WriteFormatHelper(format, new ParamsArray(arg0), appendNewLine: false); + } + else + { + base.Write(format, arg0); + } + } + + public override void Write(string format, object arg0, object arg1) + { + if (GetType() == typeof(StreamWriter)) + { + WriteFormatHelper(format, new ParamsArray(arg0, arg1), appendNewLine: false); + } + else + { + base.Write(format, arg0, arg1); + } + } + + public override void Write(string format, object arg0, object arg1, object arg2) + { + if (GetType() == typeof(StreamWriter)) + { + WriteFormatHelper(format, new ParamsArray(arg0, arg1, arg2), appendNewLine: false); + } + else + { + base.Write(format, arg0, arg1, arg2); + } + } + + public override void Write(string format, params object[] arg) + { + if (GetType() == typeof(StreamWriter)) + { + WriteFormatHelper(format, new ParamsArray(arg), appendNewLine: false); + } + else + { + base.Write(format, arg); + } + } + + public override void WriteLine(string format, object arg0) + { + if (GetType() == typeof(StreamWriter)) + { + WriteFormatHelper(format, new ParamsArray(arg0), appendNewLine: true); + } + else + { + base.WriteLine(format, arg0); + } + } + + public override void WriteLine(string format, object arg0, object arg1) + { + if (GetType() == typeof(StreamWriter)) + { + WriteFormatHelper(format, new ParamsArray(arg0, arg1), appendNewLine: true); + } + else + { + base.WriteLine(format, arg0, arg1); + } + } + + public override void WriteLine(string format, object arg0, object arg1, object arg2) + { + if (GetType() == typeof(StreamWriter)) + { + WriteFormatHelper(format, new ParamsArray(arg0, arg1, arg2), appendNewLine: true); + } + else + { + base.WriteLine(format, arg0, arg1, arg2); + } + } + + public override void WriteLine(string format, params object[] arg) + { + if (GetType() == typeof(StreamWriter)) + { + WriteFormatHelper(format, new ParamsArray(arg), appendNewLine: true); + } + else + { + base.WriteLine(format, arg); + } + } + #region Task based Async APIs public override Task WriteAsync(char value) { |