Skip to content

Instantly share code, notes, and snippets.

@dasMulli
Last active May 28, 2019 21:59
Show Gist options
  • Save dasMulli/e5b96d8a520a9c60764425e3378d0ddf to your computer and use it in GitHub Desktop.
Save dasMulli/e5b96d8a520a9c60764425e3378d0ddf to your computer and use it in GitHub Desktop.
public class CountTruesBenchmarks
{
private readonly bool[] boolArray;
public CountTruesBenchmarks()
{
var rnd = new Random(42);
boolArray = Enumerable.Range(0, 500).Select(_ => rnd.NextBoolean()).ToArray();
}
[Benchmark]
public int CountTruesFor()
{
var count = 0;
for (int i = 0; i < boolArray.Length; i++)
{
if (boolArray[i])
{
count++;
}
}
return count;
}
[Benchmark]
public int CountTruesForEach()
{
var count = 0;
foreach (var b in boolArray)
{
if (b)
{
count++;
}
}
return count;
}
[Benchmark]
public int CountTruesLinq()
{
return boolArray.Count(b => b);
}
[Benchmark]
public unsafe int CountTruesAvx2()
{
var count = 0;
if (Avx2.IsSupported)
{
var maxBatchIndex = boolArray.Length - boolArray.Length % Vector256<byte>.Count;
if (maxBatchIndex > 0)
{
var zerosVector = Vector256<byte>.Zero;
fixed (bool* boolArrayPtr = boolArray)
{
var boolArrayBytePtr = (byte*) boolArrayPtr;
for (int i = 0; i < maxBatchIndex; i += Vector256<byte>.Count)
{
var batchVector = Avx.LoadVector256(boolArrayBytePtr + i);
var comparisonResult = Avx2.CompareEqual(batchVector, zerosVector);
var nonZeroMask = ~(uint) Avx2.MoveMask(comparisonResult);
var nonZeroCount = Popcnt.PopCount(nonZeroMask);
count += (int) nonZeroCount;
}
}
}
if (maxBatchIndex < boolArray.Length)
{
for (int i = maxBatchIndex; i < boolArray.Length; i++)
{
if (boolArray[i])
{
count++;
}
}
}
}
else
{
for (int i = 0; i < boolArray.Length; i++)
{
if (boolArray[i])
{
count++;
}
}
}
return count;
}
}
BenchmarkDotNet=v0.11.5, OS=Windows 10.0.17763.529 (1809/October2018Update/Redstone5)
Intel Core i5-8350U CPU 1.70GHz (Kaby Lake R), 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=3.0.100-preview5-011568
  [Host]     : .NET Core 3.0.0-preview5-27626-15 (CoreCLR 4.6.27622.75, CoreFX 4.700.19.22408), 64bit RyuJIT
  DefaultJob : .NET Core 3.0.0-preview5-27626-15 (CoreCLR 4.6.27622.75, CoreFX 4.700.19.22408), 64bit RyuJIT

Method Mean Error StdDev
CountTruesFor 400.82 ns 2.0805 ns 1.7373 ns
CountTruesForEach 400.80 ns 2.7173 ns 2.4088 ns
CountTruesLinq 4,267.81 ns 23.5381 ns 22.0175 ns
CountTruesAvx2 29.96 ns 0.1736 ns 0.1450 ns
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment