diff --git a/test/IbanNet.Benchmark/AltMod.cs b/test/IbanNet.Benchmark/AltMod.cs new file mode 100644 index 00000000..310f4280 --- /dev/null +++ b/test/IbanNet.Benchmark/AltMod.cs @@ -0,0 +1,39 @@ +using System.Diagnostics.Contracts; +using System.Runtime.CompilerServices; + +namespace IbanNet.Benchmark; + +internal static class AltMod +{ + /// Checks the Mod97 constraint. + [Pure] + public static int Mod97(char[] iban) + { + ulong num = 0; + + // Calculate the first 4 characters (country and checksum) last + for (var i = 4; i < iban.Length; i++) + { + num = Next(num, iban[i]); + + // If we wait longer, we could overflow. + if (num >> 57 is not 0) num %= 97; + } + + // If we wait longer, we could overflow. + if (num >> 44 is not 0) num %= 97; + + for (var i = 0; i < 4; i++) + { + num = Next(num, iban[i]); + } + + return (int)(num % 97); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static ulong Next(ulong num, char ch) + => ch <= '9' + ? (num * 10) + ch - '0' + : (num * 100) + ch - 'A' + 10; + } +} diff --git a/test/IbanNet.Benchmark/Mod9710Benchmark.cs b/test/IbanNet.Benchmark/Mod9710Benchmark.cs index e381d861..9435127c 100644 --- a/test/IbanNet.Benchmark/Mod9710Benchmark.cs +++ b/test/IbanNet.Benchmark/Mod9710Benchmark.cs @@ -21,11 +21,18 @@ public static IEnumerable TestCases() ]; } + [Benchmark(Baseline = true)] + [ArgumentsSource(nameof(TestCases))] + public int Test(TestCase buffer) + { + return Mod9710.Compute(buffer.Buffer); + } + [Benchmark] [ArgumentsSource(nameof(TestCases))] - public void Test(TestCase buffer) + public int Alt(TestCase buffer) { - Mod9710.Compute(buffer.Buffer); + return AltMod.Mod97(buffer.Buffer); } public sealed class TestCase