-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove pinning from StringBuilder #64405
Conversation
I couldn't figure out the best area label to add to this PR. If you have write-permissions please help me learn by adding exactly one area label. |
Tagging subscribers to this area: @dotnet/area-system-runtime Issue DetailsSwitch from pointers to refs to avoid pinning the inputs. As part of this, I also consolidated the fast-path that was there specifically for string inputs to also apply to span inputs, char arrays, pointers, etc.
using System;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.RegularExpressions;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
[DisassemblyDiagnoser]
public class Program
{
public static void Main(string[] args) => BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);
private const int Iterations = 1000;
private StringBuilder _sb = new StringBuilder(100_000);
private char[] _chars;
private string[] _strings;
[Params("a", "ab", "abc", "abcd", "abcdefgh")]
public string Value { get; set; }
[GlobalSetup]
public void Setup()
{
_chars = Value.ToCharArray();
_strings = Enumerable.Repeat(Value, 4).ToArray();
}
[Benchmark(OperationsPerInvoke = Iterations)]
public void String()
{
_sb.Clear();
for (int i = 0; i < Iterations; i++) _sb.Append(Value);
}
[Benchmark(OperationsPerInvoke = Iterations)]
public void Span()
{
_sb.Clear();
for (int i = 0; i < Iterations; i++) _sb.Append((ReadOnlySpan<char>)Value);
}
[Benchmark(OperationsPerInvoke = Iterations)]
public void CharArray()
{
_sb.Clear();
for (int i = 0; i < Iterations; i++) _sb.Append(_chars);
}
[Benchmark(OperationsPerInvoke = Iterations)]
public void AppendJoin()
{
_sb.Clear();
for (int i = 0; i < Iterations; i++)
{
_sb.AppendJoin(", ", _strings);
}
}
}
|
Switch from pointers to refs to avoid pinning the inputs. As part of this, I also consolidated the fast-path that was there specifically for string inputs to also apply to span inputs, char arrays, pointers, etc.
Improvements on Win-x64: dotnet/perf-autofiling-issues#3219 |
Nice, thanks. |
Improvement for DateTimeOffset.ToString if it's related: dotnet/perf-autofiling-issues#3239 |
Likely. That test uses ToString(null) which will end up formatting into a StringBuilder. |
Switch from pointers to refs to avoid pinning the inputs.
As part of this, I also consolidated the fast-path that was there specifically for string inputs to also apply to span inputs, char arrays, pointers, etc.