Skip to content

Instantly share code, notes, and snippets.

@hypeartist
Created January 10, 2020 20:12
Show Gist options
  • Save hypeartist/4bef9b02f98ebbe8c5af9668de05f1fb to your computer and use it in GitHub Desktop.
Save hypeartist/4bef9b02f98ebbe8c5af9668de05f1fb to your computer and use it in GitHub Desktop.
.NET Core 3.1, IndexOf(char) test case
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
DoTest();
}
static void DoTest()
{
var fileName = @"d:\text.txt";
Text text = default;
var enc = CharsetDetector.DetectFromFile(fileName).Detected;
foreach (ReadOnlySpan<char> line in File.ReadLines(fileName, Encoding.GetEncoding(enc.EncodingName)))
{
text.Add(line);
}
var sw = new Stopwatch();
sw.Start();
var cnt = 0;
for (var i = 0; i < text.LineCount; i++)
{
var l = text[i];
var p = (UnsafePointer<char>)text[i];
cnt += CountOf1(p, l.Length, '\t');
}
sw.Stop();
var c1 = cnt;
var t1 = sw.ElapsedMilliseconds;
sw = new Stopwatch();
sw.Start();
cnt = 0;
for (var i = 0; i < text.LineCount; i++)
{
var l = text[i];
var p = (UnsafePointer<char>) text[i];
cnt += CountOf2(p, l.Length, '\t');
}
sw.Stop();
var c2 = cnt;
var t2 = sw.ElapsedMilliseconds;
sw = new Stopwatch();
sw.Start();
cnt = 0;
for (var i = 0; i < text.LineCount; i++)
{
var l = text[i];
var p = (UnsafePointer<char>)text[i];
cnt += CountOf3(p, l.Length, '\t');
}
sw.Stop();
var c3 = cnt;
var t3 = sw.ElapsedMilliseconds;
File.WriteAllLines(@"d:\indexof.txt", new[] {$"Brute: cnt={c1}, ms={t1}", $"Span: cnt={c2}, ms={t2}", $"Intrinsics: cnt={c3}, ms={t3}",});
}
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static int IndexOf1(UnsafePointer<char> chars, int length, char element, int offset = 0)
{
for (var i = offset; i < length; i++)
{
if (chars[i] != element) continue;
return i;
}
return -1;
}
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static int CountOf1(UnsafePointer<char> chars, int length, char c, int offset = 0)
{
var cnt = 0;
while (true)
{
var i = IndexOf1(chars, length, c, offset);
if (i < 0) break;
cnt++;
offset += ++i;
}
return cnt;
}
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static unsafe int IndexOf2(UnsafePointer<char> chars, int length, char element, int offset = 0)
{
if (offset >= length) return -1;
return new Span<char>((void*)(chars + offset), length - offset).IndexOf(element);
}
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static int CountOf2(UnsafePointer<char> chars, int length, char c, int offset = 0)
{
var cnt = 0;
while (true)
{
var i = IndexOf2(chars, length, c, offset);
if (i < 0) break;
cnt++;
offset += ++i;
}
return cnt;
}
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static unsafe int IndexOf3(UnsafePointer<char> chars, int length, char element, int offset)
{
if (offset >= length) return -1;
return Intrinsics.IndexOf((char*)(chars + offset), (length - offset), element);
}
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static int CountOf3(UnsafePointer<char> chars, int length, char c, int offset = 0)
{
var cnt = 0;
while (true)
{
var i = IndexOf3(chars, length, c, offset);
if (i < 0) break;
cnt++;
offset += ++i;
}
return cnt;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment