Skip to content

Instantly share code, notes, and snippets.

@guitarrapc
Last active November 6, 2021 06:17
Show Gist options
  • Save guitarrapc/c045ba10ab2477688eb4e971a6ae942c to your computer and use it in GitHub Desktop.
Save guitarrapc/c045ba10ab2477688eb4e971a6ae942c to your computer and use it in GitHub Desktop.
BenchmarkRunner.Run<BenchmarkInterpolatedHandler>();
[BenchmarkDotNet.Attributes.MemoryDiagnoser]
public class BenchmarkInterpolatedHandler
{
[Benchmark]
public void StringInterpolationInline() => PrintAInline(0);
[Benchmark]
public void StringInterpolationNoInline() => PrintANoInline(0);
[Benchmark]
public void ToStringInline() => PrintBInline(0);
[Benchmark]
public void ToStringNoInline() => PrintBNoInline(0);
[Benchmark]
public void InterpolatedStringHandlerInline() => InterpolatedStringHandlerInline(0);
[Benchmark]
public void InterpolatedStringHandlerNoInline() => InterpolatedStringHandlerNoInline(0);
// default no-inlining (!?)
string PrintANoInline(int x) => $"{x}";
[MethodImpl(MethodImplOptions.AggressiveInlining)]
string PrintAInline(int x) => $"{x}";
// default inlining
string PrintBInline(int x) => x.ToString();
[MethodImpl(MethodImplOptions.NoInlining)]
string PrintBNoInline(int x) => x.ToString();
// default no-inlining
void InterpolatedStringHandlerNoInline(int x) => WriteLine($"{x}");
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void InterpolatedStringHandlerInline(int x) => WriteLine($"{x}");
string WriteLine(DummyHandler handler) => handler.ToString();
[InterpolatedStringHandler]
public ref struct DummyHandler
{
public int LiteralLength { get; }
public int FormattedCount { get; }
private const int _formattedAverageLength = 5;
private StringBuilder _builder;
public DummyHandler(int literalLength, int formattedCount)
{
LiteralLength = literalLength;
FormattedCount = formattedCount;
_builder = new StringBuilder(literalLength + (formattedCount * _formattedAverageLength));
}
public void AppendLiteral(string s) { _builder.Append(s); }
public void AppendLiteral(int s) { _builder.Append(s.ToString()); }
public void AppendFormatted<T>(T x) { AppendLiteral(x.ToString()); }
public override string ToString() => _builder.ToString();
}
}
// Validating benchmarks:
Assembly LINQPadQuery, Version=1.0.0.501, Culture=neutral, PublicKeyToken=null is located in temp. If you are running benchmarks from xUnit you need to disable shadow copy. It's not supported by design.
// ***** BenchmarkRunner: Start *****
// * Summary *
BenchmarkDotNet=v0.13.1, OS=Windows 10.0.22000
AMD Ryzen 9 5900X, 1 CPU, 24 logical and 12 physical cores
.NET SDK=6.0.100-rc.2.21505.57
[Host] : .NET 6.0.0 (6.0.21.48005), X64 RyuJIT
| Method | Mean | Error | StdDev | Gen 0 | Allocated |
|---------------------------------- |----------:|----------:|----------:|-------:|----------:|
| StringInterpolationInline | 30.069 ns | 0.1339 ns | 0.1253 ns | 0.0014 | 24 B |
| StringInterpolationNoInline | 30.178 ns | 0.1185 ns | 0.1109 ns | 0.0014 | 24 B |
| ToStringInline | 1.294 ns | 0.0021 ns | 0.0019 ns | - | - |
| ToStringNoInline | 2.563 ns | 0.0125 ns | 0.0098 ns | - | - |
| InterpolatedStringHandlerInline | 15.288 ns | 0.1873 ns | 0.1752 ns | 0.0067 | 112 B |
| InterpolatedStringHandlerNoInline | 15.173 ns | 0.0803 ns | 0.0627 ns | 0.0067 | 112 B |
// * Legends *
Mean : Arithmetic mean of all measurements
Error : Half of 99.9% confidence interval
StdDev : Standard deviation of all measurements
Gen 0 : GC Generation 0 collects per 1000 operations
Allocated : Allocated memory per single operation (managed only, inclusive, 1KB = 1024B)
1 ns : 1 Nanosecond (0.000000001 sec)
// * Diagnostic Output - MemoryDiagnoser *
// ***** BenchmarkRunner: End *****
// ** Remained 0 benchmark(s) to run **
Run time: 00:01:52 (112.85 sec), executed benchmarks: 6
Global total time: 00:01:52 (112.85 sec), executed benchmarks: 6
// * Artifacts cleanup *
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment