From 5d637481bc5bfe46fd57e464b86e9daa20c7696d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Foidl?= Date: Sun, 3 Apr 2022 13:15:06 +0200 Subject: [PATCH] Benchmark for SpanHelpers.Contains --- src/benchmarks/micro/MicroBenchmarks.csproj | 1 + .../libraries/System.Memory/SpanHelpers.cs | 81 +++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 src/benchmarks/micro/libraries/System.Memory/SpanHelpers.cs diff --git a/src/benchmarks/micro/MicroBenchmarks.csproj b/src/benchmarks/micro/MicroBenchmarks.csproj index 39593a2f9c2..ba1921f5fac 100644 --- a/src/benchmarks/micro/MicroBenchmarks.csproj +++ b/src/benchmarks/micro/MicroBenchmarks.csproj @@ -144,6 +144,7 @@ + diff --git a/src/benchmarks/micro/libraries/System.Memory/SpanHelpers.cs b/src/benchmarks/micro/libraries/System.Memory/SpanHelpers.cs new file mode 100644 index 00000000000..28898f1629c --- /dev/null +++ b/src/benchmarks/micro/libraries/System.Memory/SpanHelpers.cs @@ -0,0 +1,81 @@ +using System.Collections.Generic; +using System.Diagnostics; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Extensions; +using MicroBenchmarks; + +namespace System.Memory +{ + [GenericTypeArguments(typeof(byte))] + [GenericTypeArguments(typeof(char))] + [BenchmarkCategory(Categories.Runtime, Categories.Libraries, Categories.Span)] + [ShortRunJob] + public unsafe class SpanHelpers + where T : unmanaged, IComparable, IEquatable + { + private T* _searchSpace; + private T _value; + + [ParamsSource(nameof(LengthValues))] + public int Length { get; set; } + + public static IEnumerable LengthValues() + { + // The values for the length take into account the different cut-offs + // in the vectorized pathes. + + if (typeof(T) == typeof(byte)) + { + // Vectorization is done on 2 * Vector.Count => 64 byte elements + yield return 63; // one less the vectorization threshould + yield return 64; // exactly two vectorized operations + yield return 65; // one element more than standard vectorized loop + yield return 95; // one element less than another iteration of the standard vectorized loop + yield return 100; + } + else if (typeof(T) == typeof(char)) + { + // Vectorization is done on 2 * Vector.Count => 32 char elements + // Values analogous to the byte values above + yield return 31; + yield return 32; + yield return 33; + yield return 47; + yield return 100; + } + else + { + throw new NotSupportedException(); + } + } + + [GlobalSetup] + public void Setup() + { + _searchSpace = (T*)NativeMemory.AlignedAlloc((uint)Length, 32); + Debug.Assert((nint)_searchSpace % Vector.Count == 0); + Unsafe.InitBlock(_searchSpace, 0x00, (uint)Length); + + _value = ValuesGenerator.GetNonDefaultValue(); + } + + [GlobalCleanup] + public void Cleanup() + { + if (_searchSpace != null) + { + NativeMemory.AlignedFree(_searchSpace); + _searchSpace = null; + } + } + + [Benchmark] + public bool Contains() + { + return new System.Span(_searchSpace, Length).Contains(_value); + } + } +}