Skip to content

Remove pinning from StringBuilder - #64405

Merged
stephentoub merged 1 commit into
dotnet:mainfrom
stephentoub:sbpin
Jan 28, 2022
Merged

Remove pinning from StringBuilder#64405
stephentoub merged 1 commit into
dotnet:mainfrom
stephentoub:sbpin

Conversation

@stephentoub

Copy link
Copy Markdown
Member

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.

MethodToolchainValueMeanRatioCode Size
String\main\corerun.exea2.958 ns1.00719 B
String\pr\corerun.exea2.127 ns0.72684 B
Span\main\corerun.exea7.652 ns1.001,170 B
Span\pr\corerun.exea2.516 ns0.33693 B
CharArray\main\corerun.exea6.631 ns1.001,171 B
CharArray\pr\corerun.exea2.133 ns0.32684 B
AppendJoin\main\corerun.exea33.384 ns1.00821 B
AppendJoin\pr\corerun.exea22.326 ns0.67811 B
String\main\corerun.exeab3.432 ns1.00719 B
String\pr\corerun.exeab2.391 ns0.70684 B
Span\main\corerun.exeab7.274 ns1.001,170 B
Span\pr\corerun.exeab2.932 ns0.40693 B
CharArray\main\corerun.exeab6.384 ns1.001,171 B
CharArray\pr\corerun.exeab2.374 ns0.37684 B
AppendJoin\main\corerun.exeab36.239 ns1.00821 B
AppendJoin\pr\corerun.exeab22.674 ns0.63811 B
String\main\corerun.exeabc4.760 ns1.00719 B
String\pr\corerun.exeabc4.348 ns0.91684 B
Span\main\corerun.exeabc7.354 ns1.001,170 B
Span\pr\corerun.exeabc4.811 ns0.66693 B
CharArray\main\corerun.exeabc6.372 ns1.001,171 B
CharArray\pr\corerun.exeabc4.330 ns0.68684 B
AppendJoin\main\corerun.exeabc38.682 ns1.00821 B
AppendJoin\pr\corerun.exeabc31.658 ns0.82811 B
String\main\corerun.exeabcd4.699 ns1.00719 B
String\pr\corerun.exeabcd4.599 ns0.98684 B
Span\main\corerun.exeabcd7.296 ns1.001,170 B
Span\pr\corerun.exeabcd4.950 ns0.68693 B
CharArray\main\corerun.exeabcd6.390 ns1.001,171 B
CharArray\pr\corerun.exeabcd4.469 ns0.70684 B
AppendJoin\main\corerun.exeabcd39.048 ns1.00821 B
AppendJoin\pr\corerun.exeabcd30.638 ns0.78811 B
String\main\corerun.exeabcdefgh4.698 ns1.00719 B
String\pr\corerun.exeabcdefgh4.504 ns0.96684 B
Span\main\corerun.exeabcdefgh7.366 ns1.001,170 B
Span\pr\corerun.exeabcdefgh5.057 ns0.69693 B
CharArray\main\corerun.exeabcdefgh6.353 ns1.001,171 B
CharArray\pr\corerun.exeabcdefgh4.546 ns0.72684 B
AppendJoin\main\corerun.exeabcdefgh39.165 ns1.00821 B
AppendJoin\pr\corerun.exeabcdefgh30.765 ns0.79811 B
usingSystem;usingSystem.Linq;usingSystem.Runtime.CompilerServices;usingSystem.Text;usingSystem.Text.RegularExpressions;usingBenchmarkDotNet.Attributes;usingBenchmarkDotNet.Running;[DisassemblyDiagnoser]publicclassProgram{publicstaticvoidMain(string[]args)=>BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);privateconstintIterations=1000;privateStringBuilder_sb=newStringBuilder(100_000);privatechar[]_chars;privatestring[]_strings;[Params("a","ab","abc","abcd","abcdefgh")]publicstringValue{get;set;}[GlobalSetup]publicvoidSetup(){_chars=Value.ToCharArray();_strings=Enumerable.Repeat(Value,4).ToArray();}[Benchmark(OperationsPerInvoke=Iterations)]publicvoidString(){_sb.Clear();for(inti=0;i<Iterations;i++)_sb.Append(Value);}[Benchmark(OperationsPerInvoke=Iterations)]publicvoidSpan(){_sb.Clear();for(inti=0;i<Iterations;i++)_sb.Append((ReadOnlySpan<char>)Value);}[Benchmark(OperationsPerInvoke=Iterations)]publicvoidCharArray(){_sb.Clear();for(inti=0;i<Iterations;i++)_sb.Append(_chars);}[Benchmark(OperationsPerInvoke=Iterations)]publicvoidAppendJoin(){_sb.Clear();for(inti=0;i<Iterations;i++){_sb.AppendJoin(", ",_strings);}}}

@ghost

Copy link
Copy Markdown

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.

@stephentoubstephentoub added this to the 7.0.0 milestone Jan 27, 2022
@ghost

Copy link
Copy Markdown

Tagging subscribers to this area: @dotnet/area-system-runtime
See info in area-owners.md if you want to be subscribed.

Issue Details

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.

MethodToolchainValueMeanRatioCode Size
String\main\corerun.exea2.958 ns1.00719 B
String\pr\corerun.exea2.127 ns0.72684 B
Span\main\corerun.exea7.652 ns1.001,170 B
Span\pr\corerun.exea2.516 ns0.33693 B
CharArray\main\corerun.exea6.631 ns1.001,171 B
CharArray\pr\corerun.exea2.133 ns0.32684 B
AppendJoin\main\corerun.exea33.384 ns1.00821 B
AppendJoin\pr\corerun.exea22.326 ns0.67811 B
String\main\corerun.exeab3.432 ns1.00719 B
String\pr\corerun.exeab2.391 ns0.70684 B
Span\main\corerun.exeab7.274 ns1.001,170 B
Span\pr\corerun.exeab2.932 ns0.40693 B
CharArray\main\corerun.exeab6.384 ns1.001,171 B
CharArray\pr\corerun.exeab2.374 ns0.37684 B
AppendJoin\main\corerun.exeab36.239 ns1.00821 B
AppendJoin\pr\corerun.exeab22.674 ns0.63811 B
String\main\corerun.exeabc4.760 ns1.00719 B
String\pr\corerun.exeabc4.348 ns0.91684 B
Span\main\corerun.exeabc7.354 ns1.001,170 B
Span\pr\corerun.exeabc4.811 ns0.66693 B
CharArray\main\corerun.exeabc6.372 ns1.001,171 B
CharArray\pr\corerun.exeabc4.330 ns0.68684 B
AppendJoin\main\corerun.exeabc38.682 ns1.00821 B
AppendJoin\pr\corerun.exeabc31.658 ns0.82811 B
String\main\corerun.exeabcd4.699 ns1.00719 B
String\pr\corerun.exeabcd4.599 ns0.98684 B
Span\main\corerun.exeabcd7.296 ns1.001,170 B
Span\pr\corerun.exeabcd4.950 ns0.68693 B
CharArray\main\corerun.exeabcd6.390 ns1.001,171 B
CharArray\pr\corerun.exeabcd4.469 ns0.70684 B
AppendJoin\main\corerun.exeabcd39.048 ns1.00821 B
AppendJoin\pr\corerun.exeabcd30.638 ns0.78811 B
String\main\corerun.exeabcdefgh4.698 ns1.00719 B
String\pr\corerun.exeabcdefgh4.504 ns0.96684 B
Span\main\corerun.exeabcdefgh7.366 ns1.001,170 B
Span\pr\corerun.exeabcdefgh5.057 ns0.69693 B
CharArray\main\corerun.exeabcdefgh6.353 ns1.001,171 B
CharArray\pr\corerun.exeabcdefgh4.546 ns0.72684 B
AppendJoin\main\corerun.exeabcdefgh39.165 ns1.00821 B
AppendJoin\pr\corerun.exeabcdefgh30.765 ns0.79811 B
usingSystem;usingSystem.Linq;usingSystem.Runtime.CompilerServices;usingSystem.Text;usingSystem.Text.RegularExpressions;usingBenchmarkDotNet.Attributes;usingBenchmarkDotNet.Running;[DisassemblyDiagnoser]publicclassProgram{publicstaticvoidMain(string[]args)=>BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);privateconstintIterations=1000;privateStringBuilder_sb=newStringBuilder(100_000);privatechar[]_chars;privatestring[]_strings;[Params("a","ab","abc","abcd","abcdefgh")]publicstringValue{get;set;}[GlobalSetup]publicvoidSetup(){_chars=Value.ToCharArray();_strings=Enumerable.Repeat(Value,4).ToArray();}[Benchmark(OperationsPerInvoke=Iterations)]publicvoidString(){_sb.Clear();for(inti=0;i<Iterations;i++)_sb.Append(Value);}[Benchmark(OperationsPerInvoke=Iterations)]publicvoidSpan(){_sb.Clear();for(inti=0;i<Iterations;i++)_sb.Append((ReadOnlySpan<char>)Value);}[Benchmark(OperationsPerInvoke=Iterations)]publicvoidCharArray(){_sb.Clear();for(inti=0;i<Iterations;i++)_sb.Append(_chars);}[Benchmark(OperationsPerInvoke=Iterations)]publicvoidAppendJoin(){_sb.Clear();for(inti=0;i<Iterations;i++){_sb.AppendJoin(", ",_strings);}}}
Author:stephentoub
Assignees:stephentoub
Labels:

area-System.Runtime, tenet-performance

Milestone:7.0.0

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.
@stephentoub
stephentoub merged commit 315fb41 into dotnet:mainJan 28, 2022
@stephentoub
stephentoub deleted the sbpin branch January 28, 2022 20:04
@EgorBo

Copy link
Copy Markdown
Member

Improvements on Win-x64: dotnet/perf-autofiling-issues#3219

@stephentoub

Copy link
Copy Markdown
MemberAuthor

Improvements on Win-x64: dotnet/perf-autofiling-issues#3219

Nice, thanks.

@EgorBo

Copy link
Copy Markdown
Member

Improvement for DateTimeOffset.ToString if it's related: dotnet/perf-autofiling-issues#3239

@stephentoub

stephentoub commented Feb 1, 2022

Copy link
Copy Markdown
MemberAuthor

if it's related

Likely. That test uses ToString(null) which will end up formatting into a StringBuilder.

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-System.Runtimetenet-performancePerformance related issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@stephentoub@EgorBo@tannergooding