-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathIndexOfAnyRunner.cs
53 lines (46 loc) · 1.54 KB
/
IndexOfAnyRunner.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
using BenchmarkDotNet.Attributes;
using System;
using System.Globalization;
using System.Linq;
namespace ConsoleAppBenchmark
{
public class IndexOfAnyRunner<T> where T : IEquatable<T>
{
[Params(4, 16, 64, 256, 1024, 4096)]
public int HaystackLength;
[Params(true, false)]
public bool LastNeedleMatches;
private T[] _haystack;
private T[] _needles;
[GlobalSetup]
public void Setup()
{
_haystack = new T[HaystackLength];
_needles = Enumerable.Range('a', 6).Select(el => (T)Convert.ChangeType(el, typeof(T), CultureInfo.InvariantCulture)).ToArray();
T needle = (LastNeedleMatches) ? _needles.Last() : _needles.First();
for (int i = 0; i < _haystack.Length; i += 4)
{
_haystack[i] = needle;
}
}
[Benchmark]
public int SliceInALoop()
{
var haystack = _haystack;
_ = haystack.Length; // allow JIT to prove not null
ReadOnlySpan<T> haystackSpan = haystack;
var needles = _needles;
_ = needles.Length; // allow JIT to prove not null
ReadOnlySpan<T> needlesSpan = needles;
while (true)
{
int idx = haystackSpan.IndexOfAny(needlesSpan);
if (idx < 0)
{
return haystackSpan.Length; // length of final slice
}
haystackSpan = haystackSpan.Slice(idx + 1);
}
}
}
}