Skip to content

Commit

Permalink
Optimize ReusableStringWriter.Write/WriteLine(ReadOnlySpan<char>) met…
Browse files Browse the repository at this point in the history
…hods

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.
  • Loading branch information
epeshk authored and nblumhardt committed Aug 20, 2024
1 parent 9f6b814 commit 3f6d855
Showing 1 changed file with 14 additions and 2 deletions.
16 changes: 14 additions & 2 deletions src/Serilog/Rendering/ReusableStringWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ namespace Serilog.Rendering;
/// <summary>
/// Class that provides reusable StringWriters to reduce memory allocations
/// </summary>
class ReusableStringWriter : StringWriter
sealed class ReusableStringWriter : StringWriter
{
[ThreadStatic]
static ReusableStringWriter? _pooledWriter;
Expand Down Expand Up @@ -52,8 +52,20 @@ protected override void Dispose(bool disposing)
return;
}
// We don't call base.Dispose because all it does is mark the writer as closed so it can't be
// written to and we want to keep it open as reusable writer.
// written to, and we want to keep it open as reusable writer.
sb.Clear();
_pooledWriter = this;
}

#if FEATURE_SPAN
public override void Write(ReadOnlySpan<char> buffer)
{
GetStringBuilder().Append(buffer);
}

public override void WriteLine(ReadOnlySpan<char> buffer)
{
GetStringBuilder().Append(buffer).AppendLine();
}
#endif
}

0 comments on commit 3f6d855

Please sign in to comment.