using BenchmarkDotNet.Attributes; namespace Benchmarks.Console.Misc; [MemoryDiagnoser] public class BoundaryChecking { private static readonly int[] _array32; private static readonly long[] _array64; private static readonly int _boundary32; private static readonly long _boundary64; private volatile bool _x0; private volatile bool _x1; private volatile bool _x2; private volatile bool _x3; private volatile bool _x4; private volatile bool _x5; private volatile bool _x6; private volatile bool _x7; private volatile bool _x8; private volatile bool _x9; static BoundaryChecking() { _array32 = new int[100_000]; _array64 = new long[100_000]; _boundary32 = new Random().Next(); _boundary64 = new Random().NextInt64(); } [Benchmark] public void Simple32() { _x0 = _array32[0] >= 0 && _array32[0] < _boundary32; _x1 = _array32[1] >= 0 && _array32[1] < _boundary32; _x2 = _array32[2] >= 0 && _array32[2] < _boundary32; _x3 = _array32[3] >= 0 && _array32[3] < _boundary32; _x4 = _array32[4] >= 0 && _array32[4] < _boundary32; _x5 = _array32[5] >= 0 && _array32[5] < _boundary32; _x6 = _array32[6] >= 0 && _array32[6] < _boundary32; _x7 = _array32[7] >= 0 && _array32[7] < _boundary32; _x8 = _array32[8] >= 0 && _array32[8] < _boundary32; _x9 = _array32[9] >= 0 && _array32[9] < _boundary32; } [Benchmark] public void Simple64() { _x0 = _array64[0] >= 0 && _array64[0] < _boundary64; _x1 = _array64[1] >= 0 && _array64[1] < _boundary64; _x2 = _array64[2] >= 0 && _array64[2] < _boundary64; _x3 = _array64[3] >= 0 && _array64[3] < _boundary64; _x4 = _array64[4] >= 0 && _array64[4] < _boundary64; _x5 = _array64[5] >= 0 && _array64[5] < _boundary64; _x6 = _array64[6] >= 0 && _array64[6] < _boundary64; _x7 = _array64[7] >= 0 && _array64[7] < _boundary64; _x8 = _array64[8] >= 0 && _array64[8] < _boundary64; _x9 = _array64[9] >= 0 && _array64[9] < _boundary64; } [Benchmark] public void Optimized32() { _x0 = (uint)_array32[0] < (uint)_boundary32; _x1 = (uint)_array32[1] < (uint)_boundary32; _x2 = (uint)_array32[2] < (uint)_boundary32; _x3 = (uint)_array32[3] < (uint)_boundary32; _x4 = (uint)_array32[4] < (uint)_boundary32; _x5 = (uint)_array32[5] < (uint)_boundary32; _x6 = (uint)_array32[6] < (uint)_boundary32; _x7 = (uint)_array32[7] < (uint)_boundary32; _x8 = (uint)_array32[8] < (uint)_boundary32; _x9 = (uint)_array32[9] < (uint)_boundary32; } [Benchmark] public void Optimized64() { _x0 = (ulong)_array64[0] < (ulong)_boundary64; _x1 = (ulong)_array64[1] < (ulong)_boundary64; _x2 = (ulong)_array64[2] < (ulong)_boundary64; _x3 = (ulong)_array64[3] < (ulong)_boundary64; _x4 = (ulong)_array64[4] < (ulong)_boundary64; _x5 = (ulong)_array64[5] < (ulong)_boundary64; _x6 = (ulong)_array64[6] < (ulong)_boundary64; _x7 = (ulong)_array64[7] < (ulong)_boundary64; _x8 = (ulong)_array64[8] < (ulong)_boundary64; _x9 = (ulong)_array64[9] < (ulong)_boundary64; } [Benchmark] public (long, long) SimpleIteration32() { long inBoundary = 0; long outBoundary = 0; var array = _array32.AsSpan(); for (var i = 0; i < array.Length; ++i) { if (array[i] >= 0 && array[i] < _boundary32) ++inBoundary; else ++outBoundary; } return (inBoundary, outBoundary); } [Benchmark] public (long, long) SimpleIteration64() { long inBoundary = 0; long outBoundary = 0; var array = _array64.AsSpan(); for (var i = 0; i < array.Length; ++i) { if (array[i] >= 0 && array[i] < _boundary64) ++inBoundary; else ++outBoundary; } return (inBoundary, outBoundary); } [Benchmark] public (long, long) OptimizedIteration32() { long inBoundary = 0; long outBoundary = 0; var array = _array32.AsSpan(); for (var i = 0; i < array.Length; ++i) { if ((uint)array[i] < (uint)_boundary32) ++inBoundary; else ++outBoundary; } return (inBoundary, outBoundary); } [Benchmark] public (long, long) OptimizedIteration64() { long inBoundary = 0; long outBoundary = 0; var array = _array64.AsSpan(); for (var i = 0; i < array.Length; ++i) { if ((ulong)array[i] < (ulong)_boundary64) ++inBoundary; else ++outBoundary; } return (inBoundary, outBoundary); } }