Created
December 6, 2022 07:48
-
-
Save michal-ciechan/0a53518076bff6253395d6456dc9f11f to your computer and use it in GitHub Desktop.
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 BenchmarkDotNet.Attributes; | |
using BenchmarkDotNet.Jobs; | |
namespace MikeysBenchmarks; | |
[SimpleJob(RuntimeMoniker.Net70)] | |
[MemoryDiagnoser()] | |
[MarkdownExporter] | |
public class SpanTrimZ | |
{ | |
private const string _withUtc = "2022-12-05T11:11:23Z"; | |
private const string _withoutUtc = "2022-12-05T11:11:23"; | |
private static readonly char[] _z = new char[1] | |
{ | |
'Z' | |
}; | |
[GlobalSetup] | |
public void GlobalSetup() | |
{ | |
} | |
[ParamsAllValues] | |
public bool WithUtc { get; set; } | |
public string String => WithUtc ? _withUtc : _withoutUtc; | |
[Benchmark] | |
public int StringTrimEnd() | |
{ | |
var str = String.TrimEnd('Z').TrimEnd('z'); | |
var isUtc = str.Length < String.Length; | |
var utcOffset = isUtc ? 1 : 0; | |
return str.Length + utcOffset; | |
} | |
[Benchmark] | |
public int CompareStackalloc_TrimEnd() | |
{ | |
var span = String.AsSpan(); | |
var utcOffset = 0; | |
Span<char> s = stackalloc char[1] | |
{ | |
'Z' | |
}; | |
if (span.EndsWith(s, StringComparison.OrdinalIgnoreCase)) | |
{ | |
span = span.TrimEnd('Z').TrimEnd('z'); | |
utcOffset = 1; | |
} | |
return span.Length + utcOffset; | |
} | |
[Benchmark] | |
public int CompareStackalloc_Range() | |
{ | |
var span = String.AsSpan(); | |
var utcOffset = 0; | |
Span<char> s = stackalloc char[1] | |
{ | |
'Z' | |
}; | |
if (span.EndsWith(s, StringComparison.OrdinalIgnoreCase)) | |
{ | |
span = span[..^1]; | |
utcOffset = 1; | |
} | |
return span.Length + utcOffset; | |
} | |
[Benchmark] | |
public int CompareStackalloc_Length() | |
{ | |
var span = String.AsSpan(); | |
var utcOffset = 0; | |
Span<char> s = stackalloc char[1] | |
{ | |
'Z' | |
}; | |
if (span.EndsWith(s, StringComparison.OrdinalIgnoreCase)) | |
{ | |
span = span.Slice(0, span.Length - 1); | |
utcOffset = 1; | |
} | |
return span.Length + utcOffset; | |
} | |
[Benchmark] | |
public int CompareArray_Length() | |
{ | |
var span = String.AsSpan(); | |
var utcOffset = 0; | |
var c = _z.AsSpan(); | |
if (span.EndsWith(c, StringComparison.OrdinalIgnoreCase)) | |
{ | |
span = span.Slice(0, span.Length - 1); | |
utcOffset = 1; | |
} | |
return span.Length + utcOffset; | |
} | |
[Benchmark] | |
public int CompareArray_Range() | |
{ | |
var span = String.AsSpan(); | |
var utcOffset = 0; | |
var c = _z.AsSpan(); | |
if (span.EndsWith(c, StringComparison.OrdinalIgnoreCase)) | |
{ | |
span = span[..^1]; | |
utcOffset = 1; | |
} | |
return span.Length + utcOffset; | |
} | |
[Benchmark] | |
public int CompareArray_TrimEnd() | |
{ | |
var span = String.AsSpan(); | |
var utcOffset = 0; | |
var c = _z.AsSpan(); | |
if (span.EndsWith(c, StringComparison.OrdinalIgnoreCase)) | |
{ | |
span = span.TrimEnd('Z').TrimEnd('z'); | |
utcOffset = 1; | |
} | |
return span.Length + utcOffset; | |
} | |
[Benchmark] | |
public int StringEndsWith_Range() | |
{ | |
var span = String.AsSpan(); | |
var utcOffset = 0; | |
if (String.EndsWith("Z", StringComparison.OrdinalIgnoreCase)) | |
{ | |
span = span[..^1]; | |
utcOffset = 1; | |
} | |
return span.Length + utcOffset; | |
} | |
[Benchmark] | |
public int SpanTrimEndWithCheck() | |
{ | |
var span = String.AsSpan(); | |
var span2 = span.TrimEnd('Z').TrimEnd('z'); | |
var isUtc = span2.Length < span.Length; | |
var utcOffset = isUtc ? 1 : 0; | |
return span.Length + utcOffset; | |
} | |
} | |
/* | |
// * Summary * | |
BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19043.1348/21H1/May2021Update), VM=VMware | |
AMD EPYC 7713P, 1 CPU, 12 logical and 12 physical cores | |
.NET SDK=7.0.100-rc.2.22477.23 | |
[Host] : .NET 6.0.10 (6.0.1022.47605), X64 RyuJIT AVX2 | |
.NET 7.0 : .NET 7.0.0 (7.0.22.47203), X64 RyuJIT AVX2 | |
Job=.NET 7.0 Runtime=.NET 7.0 | |
| Method | WithUtc | Mean | Error | StdDev | Gen0 | Allocated | | |
|-------------------------- |-------- |----------:|----------:|----------:|-------:|----------:| | |
| StringTrimEnd | False | 10.510 ns | 0.2319 ns | 0.1936 ns | - | - | | |
| CompareStackalloc_TrimEnd | False | 5.326 ns | 0.0705 ns | 0.0589 ns | - | - | | |
| CompareStackalloc_Range | False | 5.812 ns | 0.1114 ns | 0.0987 ns | - | - | | |
| CompareStackalloc_Length | False | 5.555 ns | 0.1105 ns | 0.1033 ns | - | - | | |
| CompareArray_Length | False | 5.026 ns | 0.0475 ns | 0.0371 ns | - | - | | |
| CompareArray_Range | False | 5.013 ns | 0.0982 ns | 0.0918 ns | - | - | | |
| CompareArray_TrimEnd | False | 5.426 ns | 0.1222 ns | 0.1143 ns | - | - | | |
| StringEndsWith_Range | False | 9.735 ns | 0.1929 ns | 0.1804 ns | - | - | | |
| SpanTrimEndWithCheck | False | 2.866 ns | 0.0879 ns | 0.0822 ns | - | - | | |
| StringTrimEnd | True | 22.666 ns | 0.3861 ns | 0.3423 ns | 0.0007 | 64 B | | |
| CompareStackalloc_TrimEnd | True | 6.663 ns | 0.0746 ns | 0.0582 ns | - | - | | |
| CompareStackalloc_Range | True | 5.308 ns | 0.0518 ns | 0.0405 ns | - | - | | |
| CompareStackalloc_Length | True | 5.114 ns | 0.1376 ns | 0.1287 ns | - | - | | |
| CompareArray_Length | True | 4.364 ns | 0.0474 ns | 0.0420 ns | - | - | | |
| CompareArray_Range | True | 4.387 ns | 0.0618 ns | 0.0548 ns | - | - | | |
| CompareArray_TrimEnd | True | 6.434 ns | 0.1147 ns | 0.1178 ns | - | - | | |
| StringEndsWith_Range | True | 10.174 ns | 0.2208 ns | 0.2168 ns | - | - | | |
| SpanTrimEndWithCheck | True | 4.105 ns | 0.0843 ns | 0.0788 ns | - | - | | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment