Open2
C# Benchmark
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Running;
namespace StringBenchmark
{
internal class Program
{
static void Main(string[] args)
{
BenchmarkRunner.Run<StringStartsWithMeasurement>();
}
}
[SimpleJob(RuntimeMoniker.Net472)]
[SimpleJob(RuntimeMoniker.Net60)]
public class StringStartsWithMeasurement
{
[Params("hoge")]
public string Value = string.Empty;
public string Start;
[Params('a')]
public char StartChar;
[GlobalSetup]
public void Setup()
{
Start = StartChar.ToString();
}
[Benchmark]
public bool StartsWithString()
{
return Value.StartsWith(Start);
}
[Benchmark(Baseline = true)]
public bool StartsWithChar()
{
#if NETCOREAPP
return Value.StartsWith(StartChar);
#else
return Value.Length != 0 && Value[0] == StartChar;
#endif
}
}
}
// * Summary *
BenchmarkDotNet=v0.13.5, OS=Windows 10 (10.0.19045.2965/22H2/2022Update)
11th Gen Intel Core i7-11700K 3.60GHz, 1 CPU, 16 logical and 8 physical cores
[Host] : .NET Framework 4.8 (4.8.4614.0), X64 RyuJIT VectorSize=256
.NET 6.0 : .NET 6.0.16 (6.0.1623.17311), X64 RyuJIT AVX2
.NET Framework 4.7.2 : .NET Framework 4.8 (4.8.4614.0), X64 RyuJIT VectorSize=256
| Method | Job | Runtime | Value | StartChar | Mean | Error | StdDev | Ratio | RatioSD |
|----------------- |--------------------- |--------------------- |------ |---------- |------------:|----------:|----------:|---------:|---------:|
| StartsWithString | .NET 6.0 | .NET 6.0 | hoge | a | 411.7495 ns | 4.9672 ns | 4.4033 ns | 8,972.02 | 4,838.40 |
| StartsWithChar | .NET 6.0 | .NET 6.0 | hoge | a | 0.0542 ns | 0.0226 ns | 0.0211 ns | 1.00 | 0.00 |
| | | | | | | | | | |
| StartsWithString | .NET Framework 4.7.2 | .NET Framework 4.7.2 | hoge | a | 75.1370 ns | 1.0416 ns | 0.8698 ns | 321.76 | 28.45 |
| StartsWithChar | .NET Framework 4.7.2 | .NET Framework 4.7.2 | hoge | a | 0.2369 ns | 0.0205 ns | 0.0192 ns | 1.00 | 0.00 |
// * Hints *
Outliers
StringStartsWithMeasurement.StartsWithString: .NET 6.0 -> 1 outlier was removed (433.87 ns)
StringStartsWithMeasurement.StartsWithChar: .NET 6.0 -> 2 outliers were removed (1.22 ns, 1.26 ns)
StringStartsWithMeasurement.StartsWithString: .NET Framework 4.7.2 -> 4 outliers were removed (81.08 ns..113.23 ns)
// * Legends *
Value : Value of the 'Value' parameter
StartChar : Value of the 'StartChar' parameter
Mean : Arithmetic mean of all measurements
Error : Half of 99.9% confidence interval
StdDev : Standard deviation of all measurements
Ratio : Mean of the ratio distribution ([Current]/[Baseline])
RatioSD : Standard deviation of the ratio distribution ([Current]/[Baseline])
1 ns : 1 Nanosecond (0.000000001 sec)
// ***** BenchmarkRunner: End *****
Run time: 00:01:39 (99.48 sec), executed benchmarks: 4
Global total time: 00:01:45 (105.41 sec), executed benchmarks: 4
// * Artifacts cleanup *
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Running;
namespace StringBenchmark
{
internal class Program
{
static void Main(string[] args)
{
BenchmarkRunner.Run<StringStartsWithMeasurement>();
}
}
[SimpleJob(RuntimeMoniker.Net472)]
[SimpleJob(RuntimeMoniker.Net60)]
[SimpleJob(RuntimeMoniker.Net80)]
public class StringStartsWithMeasurement
{
[Params("hoge")]
public string Value = string.Empty;
public char ValueFirstChar;
public string Start;
[Params('a')]
public char StartChar;
[GlobalSetup]
public void Setup()
{
Start = StartChar.ToString();
ValueFirstChar = Value[0];
}
[Benchmark]
public bool StartsWithString()
{
return Value.StartsWith(Start);
}
[Benchmark]
public bool StartsWithChar()
{
return Value.StartsWith(StartChar);
}
[Benchmark(Baseline = true)]
public bool StartsWithCharInline()
{
return Value.Length != 0 && ValueFirstChar == StartChar;
}
}
#if !NETCOREAPP
public static class StringExtensions
{
public static bool StartsWith(this string value, char c)
{
return value.Length != 0 && value[0] == c;
}
}
#endif
}
// * Summary *
BenchmarkDotNet=v0.13.5, OS=Windows 10 (10.0.19045.3930/22H2/2022Update)
11th Gen Intel Core i7-11700K 3.60GHz, 1 CPU, 16 logical and 8 physical cores
[Host] : .NET Framework 4.8.1 (4.8.9181.0), X64 RyuJIT VectorSize=256
.NET 6.0 : .NET 6.0.26 (6.0.2623.60508), X64 RyuJIT AVX2
.NET 8.0 : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2
.NET Framework 4.7.2 : .NET Framework 4.8.1 (4.8.9181.0), X64 RyuJIT VectorSize=256
| Method | Job | Runtime | Value | StartChar | Mean | Error | StdDev | Median | Ratio | RatioSD |
|--------------------- |--------------------- |--------------------- |------ |---------- |------------:|----------:|----------:|------------:|----------:|----------:|
| StartsWithString | .NET 6.0 | .NET 6.0 | hoge | a | 431.5507 ns | 5.3370 ns | 4.9922 ns | 432.4835 ns | ? | ? |
| StartsWithChar | .NET 6.0 | .NET 6.0 | hoge | a | 0.0002 ns | 0.0009 ns | 0.0008 ns | 0.0000 ns | ? | ? |
| StartsWithCharInline | .NET 6.0 | .NET 6.0 | hoge | a | 0.0023 ns | 0.0061 ns | 0.0054 ns | 0.0000 ns | ? | ? |
| | | | | | | | | | | |
| StartsWithString | .NET 8.0 | .NET 8.0 | hoge | a | 391.5178 ns | 5.3790 ns | 5.0316 ns | 391.5569 ns | 12,366.17 | 12,603.52 |
| StartsWithChar | .NET 8.0 | .NET 8.0 | hoge | a | 0.5557 ns | 0.0168 ns | 0.0158 ns | 0.5571 ns | 17.59 | 17.83 |
| StartsWithCharInline | .NET 8.0 | .NET 8.0 | hoge | a | 0.0501 ns | 0.0238 ns | 0.0293 ns | 0.0476 ns | 1.00 | 0.00 |
| | | | | | | | | | | |
| StartsWithString | .NET Framework 4.7.2 | .NET Framework 4.7.2 | hoge | a | 71.8030 ns | 1.4381 ns | 1.4768 ns | 71.7366 ns | ? | ? |
| StartsWithChar | .NET Framework 4.7.2 | .NET Framework 4.7.2 | hoge | a | 0.6707 ns | 0.0290 ns | 0.0271 ns | 0.6792 ns | ? | ? |
| StartsWithCharInline | .NET Framework 4.7.2 | .NET Framework 4.7.2 | hoge | a | 0.0000 ns | 0.0000 ns | 0.0000 ns | 0.0000 ns | ? | ? |
// * Warnings *
ZeroMeasurement
StringStartsWithMeasurement.StartsWithChar: .NET 6.0 -> The method duration is indistinguishable from the empty method duration
StringStartsWithMeasurement.StartsWithCharInline: .NET 6.0 -> The method duration is indistinguishable from the empty method duration
StringStartsWithMeasurement.StartsWithCharInline: .NET Framework 4.7.2 -> The method duration is indistinguishable from the empty method duration
BaselineCustomAnalyzer
Summary -> A question mark '?' symbol indicates that it was not possible to compute the (Ratio, RatioSD) column(s) because the baseline value is too close to zero.
// * Hints *
Outliers
StringStartsWithMeasurement.StartsWithString: .NET 6.0 -> 1 outlier was detected (420.34 ns)
StringStartsWithMeasurement.StartsWithChar: .NET 6.0 -> 1 outlier was removed (1.12 ns)
StringStartsWithMeasurement.StartsWithCharInline: .NET 6.0 -> 1 outlier was removed (1.13 ns)
StringStartsWithMeasurement.StartsWithCharInline: .NET 8.0 -> 1 outlier was removed (1.33 ns)
StringStartsWithMeasurement.StartsWithChar: .NET Framework 4.7.2 -> 2 outliers were removed (1.83 ns, 1.84 ns)
// * Legends *
Value : Value of the 'Value' parameter
StartChar : Value of the 'StartChar' parameter
Mean : Arithmetic mean of all measurements
Error : Half of 99.9% confidence interval
StdDev : Standard deviation of all measurements
Median : Value separating the higher half of all measurements (50th percentile)
Ratio : Mean of the ratio distribution ([Current]/[Baseline])
RatioSD : Standard deviation of the ratio distribution ([Current]/[Baseline])
1 ns : 1 Nanosecond (0.000000001 sec)
// ***** BenchmarkRunner: End *****
Run time: 00:04:29 (269 sec), executed benchmarks: 9
Global total time: 00:04:36 (276.11 sec), executed benchmarks: 9
// * Artifacts cleanup *