Skip to content

Commit 3f6d855

Browse files
epeshknblumhardt
authored andcommitted
Optimize ReusableStringWriter.Write/WriteLine(ReadOnlySpan<char>) methods
Original StringWriter.Write/WriteLine(ReadOnlySpan<char>) methods are optimized only for the StringWriter type itself, not derived classes. For derived classes, these methods copy the provided Span to an array from ArrayPool and fall back to Write(char[], int, int) method for backward compatibility with code created before the Span type existed. Explicit overrides in the ReusableStringWriter class that call StringBuilder.Append directly help to avoid the overhead of ArrayPool.Rent/Return and copying.
1 parent 9f6b814 commit 3f6d855

File tree

1 file changed

+14
-2
lines changed

1 file changed

+14
-2
lines changed

src/Serilog/Rendering/ReusableStringWriter.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ namespace Serilog.Rendering;
33
/// <summary>
44
/// Class that provides reusable StringWriters to reduce memory allocations
55
/// </summary>
6-
class ReusableStringWriter : StringWriter
6+
sealed class ReusableStringWriter : StringWriter
77
{
88
[ThreadStatic]
99
static ReusableStringWriter? _pooledWriter;
@@ -52,8 +52,20 @@ protected override void Dispose(bool disposing)
5252
return;
5353
}
5454
// We don't call base.Dispose because all it does is mark the writer as closed so it can't be
55-
// written to and we want to keep it open as reusable writer.
55+
// written to, and we want to keep it open as reusable writer.
5656
sb.Clear();
5757
_pooledWriter = this;
5858
}
59+
60+
#if FEATURE_SPAN
61+
public override void Write(ReadOnlySpan<char> buffer)
62+
{
63+
GetStringBuilder().Append(buffer);
64+
}
65+
66+
public override void WriteLine(ReadOnlySpan<char> buffer)
67+
{
68+
GetStringBuilder().Append(buffer).AppendLine();
69+
}
70+
#endif
5971
}

0 commit comments

Comments
 (0)