Created
September 7, 2016 19:26
-
-
Save phil-scott-78/686c8cd8cd1353884b60b74231923aac to your computer and use it in GitHub Desktop.
String Builder Benchmarks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Text; | |
using BenchmarkDotNet.Attributes; | |
using BenchmarkDotNet.Configs; | |
using BenchmarkDotNet.Diagnostics.Windows; | |
using BenchmarkDotNet.Running; | |
namespace StringBuilderBenchmarks | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
var summary = BenchmarkRunner.Run<StringBuilderBenchmark>(); | |
} | |
} | |
[Config(typeof(Config))] | |
public class StringBuilderBenchmark | |
{ | |
private class Config : ManualConfig | |
{ | |
public Config() | |
{ | |
Add(new MemoryDiagnoser()); | |
} | |
} | |
private readonly string _firstPart = DateTime.Now.ToString("ddd"); | |
private readonly string _secondPart = DateTime.Now.ToString("MMMM"); | |
private const int RunCount = 10000; | |
[Benchmark] | |
public string AppendFormatWithNewLineInFormat() | |
{ | |
var sb = new StringBuilder(); | |
for (var i = 0; i < RunCount; i++) | |
{ | |
sb.AppendFormat("{0}:{1}{2}", _firstPart, _secondPart, Environment.NewLine); | |
} | |
return sb.ToString(); | |
} | |
[Benchmark] | |
public string AppendFormatWithAppendLine() | |
{ | |
var sb = new StringBuilder(); | |
for (var i = 0; i < RunCount; i++) | |
{ | |
sb.AppendFormat("{0}:{1}", _firstPart, _secondPart).AppendLine(); | |
} | |
return sb.ToString(); | |
} | |
[Benchmark] | |
public string AppendLineWithStringInterpolation() | |
{ | |
var sb = new StringBuilder(); | |
for (var i = 0; i < RunCount; i++) | |
{ | |
sb.AppendLine($"{_firstPart}:{_secondPart}"); | |
} | |
return sb.ToString(); | |
} | |
[Benchmark] | |
public string NaiveAppendFormatLine() | |
{ | |
var sb = new StringBuilder(); | |
for (var i = 0; i < RunCount; i++) | |
{ | |
sb.NaiveAppendFormatLine("{0}:{1}", _firstPart, _secondPart); | |
} | |
return sb.ToString(); | |
} | |
[Benchmark] | |
public string AppendFormatLine() | |
{ | |
var sb = new StringBuilder(); | |
for (var i = 0; i < RunCount; i++) | |
{ | |
sb.AppendFormatLine("{0}:{1}", _firstPart, _secondPart); | |
} | |
return sb.ToString(); | |
} | |
[Benchmark] | |
public string AppendFormatWithEscapedNewLine() | |
{ | |
var sb = new StringBuilder(); | |
for (var i = 0; i < RunCount; i++) | |
{ | |
sb.AppendFormat("{0}:{1}\r\n", _firstPart, _secondPart); | |
} | |
return sb.ToString(); | |
} | |
[Benchmark] | |
public string AppendFormatWithEnvironmentNewLine() | |
{ | |
var sb = new StringBuilder(); | |
var format = "{0}:{1}" + Environment.NewLine; | |
for (var i = 0; i < RunCount; i++) | |
{ | |
sb.AppendFormat(format, _firstPart, _secondPart); | |
} | |
return sb.ToString(); | |
} | |
} | |
static class StringBuilderExtentions | |
{ | |
public static StringBuilder NaiveAppendFormatLine(this StringBuilder sb, string format, params object[] args) | |
{ | |
// knowing the AppendFormat with AppendLine is going to be generally the fastest | |
// without having to rely on hard coding the new line or some verbose code to apply the newline | |
// out of the loop an extension method makes sense. But the example you'll see | |
// for this is counter-productive (e.g. http://stackoverflow.com/a/18729210/54342) and uses | |
// a param array. To do this right we'll need to match all the overloads of stringBuilder.AppendFormat | |
// to reduce the number of allocations needed for many cases | |
return sb.AppendFormat(format, args).AppendLine(); | |
} | |
public static StringBuilder AppendFormatLine(this StringBuilder sb, string format, object arg0, object arg1) | |
{ | |
return sb.AppendFormat(format, arg0, arg1).AppendLine(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment