using System; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using System.Runtime.Intrinsics.X86; using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Columns; using BenchmarkDotNet.Configs; using BenchmarkDotNet.Jobs; using BenchmarkDotNet.Reports; using BenchmarkDotNet.Running; class Program { public static void Main() { BenchmarkRunner.Run(new LocalCoreClrConfig()); } } public class CountDigitsBenchmark { [Params(0ul, 0xAul, 0x42ul, 0x123ul, 0xDEADF00ul, 0xDEADF00D12345ul)] public ulong Number { get; set; } [Benchmark] public int CountHexDigits_original() => CountHexDigits_original(Number); [Benchmark(Baseline = true)] public int CountHexDigits_Lzcnt_shifts() => CountHexDigits_Lzcnt_shifts(Number); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int CountHexDigits_Lzcnt_shifts(ulong value) { if (Lzcnt.IsSupported) { var right = 64 - (int)Lzcnt.LeadingZeroCount(value | 1); return (right + 3) >> 2; } int digits = 1; if (value > 0xFFFFFFFF) { digits += 8; value >>= 0x20; } if (value > 0xFFFF) { digits += 4; value >>= 0x10; } if (value > 0xFF) { digits += 2; value >>= 0x8; } if (value > 0xF) digits++; return digits; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int CountHexDigits_original(ulong value) { int digits = 1; if (value > 0xFFFFFFFF) { digits += 8; value >>= 0x20; } if (value > 0xFFFF) { digits += 4; value >>= 0x10; } if (value > 0xFF) { digits += 2; value >>= 0x8; } if (value > 0xF) digits++; return digits; } }