Small refactoring
This commit is contained in:
1 parent
412ce4fd50
commit
2c2bc62cb2
3 files changed
+80
-37
No files matched your search
@@ -0,0 +1,65 @@
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using PerfectNumbers.Core;
|
||||
|
||||
namespace EvenPerfectBitScanner.Benchmarks;
|
||||
|
||||
[MemoryDiagnoser]
|
||||
public class Mod10_8_5_3PropertiesBenchmarks
|
||||
{
|
||||
public ulong Mod10R;
|
||||
public ulong Mod8R;
|
||||
public ulong Mod3R;
|
||||
public ulong Mod5R;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static ulong Mod8(UInt128 value) => (ulong)value & 7UL;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static ulong Mod3(UInt128 value)
|
||||
{
|
||||
// 2^64 ≡ 1 (mod 3)
|
||||
ulong high = (ulong)(value >> 64);
|
||||
ulong low = (ulong)value;
|
||||
ulong rem = (low % 3UL) + (high % 3UL);
|
||||
return rem >= 3UL ? rem - 3UL : rem;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static ulong Mod5(UInt128 value)
|
||||
{
|
||||
// 2^64 ≡ 1 (mod 5)
|
||||
ulong high = (ulong)(value >> 64);
|
||||
ulong low = (ulong)value;
|
||||
ulong rem = (low % 5UL) + (high % 5UL);
|
||||
return rem >= 5UL ? rem - 5UL : rem;
|
||||
}
|
||||
|
||||
[Params(3UL, 8191UL, 131071UL, 2147483647UL)]
|
||||
public ulong Value { get; set; }
|
||||
|
||||
[Benchmark(Baseline = true)]
|
||||
public (ulong Mod10, ulong Mod8, ulong Mod5, ulong Mod3) LegacyModulo()
|
||||
{
|
||||
UInt128 value = Value;
|
||||
Mod10R = value.Mod10();
|
||||
Mod8R = Mod8(value);
|
||||
Mod5R = Mod5(value);
|
||||
Mod3R = Mod3(value);
|
||||
return (Mod10R, Mod8R, Mod5R, Mod3R);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public (ulong Mod10, ulong Mod8, ulong Mod3, ulong Mod5) ModMethodModulo()
|
||||
{
|
||||
Value.Mod10_8_5_3(out var mod10, out ulong mod8, out ulong mod5, out ulong mod3);
|
||||
Mod10R = mod10;
|
||||
Mod8R = mod8;
|
||||
Mod5R = mod5;
|
||||
Mod3R = mod3;
|
||||
|
||||
return (Mod10R, Mod8R, Mod3R, Mod5R);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,11 +12,11 @@ public sealed class MersenneResidueAutomaton
|
||||
private readonly UInt128 _step; // 2*p
|
||||
private UInt128 _currentQ; // current q value
|
||||
|
||||
// Cached residues for current q
|
||||
public ulong Mod10R { get; private set; }
|
||||
public ulong Mod8R { get; private set; }
|
||||
public ulong Mod3R { get; private set; }
|
||||
public ulong Mod5R { get; private set; }
|
||||
// Cached residues for current q
|
||||
public ulong Mod10R;
|
||||
public ulong Mod8R;
|
||||
public ulong Mod3R;
|
||||
public ulong Mod5R;
|
||||
|
||||
// Cached residues for step (2*p mod m)
|
||||
private readonly ulong _step10;
|
||||
@@ -27,18 +27,18 @@ public sealed class MersenneResidueAutomaton
|
||||
public MersenneResidueAutomaton(ulong exponent)
|
||||
{
|
||||
_step = (UInt128)exponent << 1; // 2 * p
|
||||
_currentQ = _step + 1UL; // start at k = 1
|
||||
_currentQ = _step + UInt128.One; // start at k = 1
|
||||
|
||||
// init residues
|
||||
// init residues
|
||||
Mod10R = _currentQ.Mod10();
|
||||
Mod8R = Mod8(_currentQ);
|
||||
Mod3R = Mod3(_currentQ);
|
||||
Mod5R = Mod5(_currentQ);
|
||||
Mod8R = _currentQ.Mod8();
|
||||
Mod3R = _currentQ.Mod3();
|
||||
Mod5R = _currentQ.Mod5();
|
||||
|
||||
_step10 = _step.Mod10().Mod10();
|
||||
_step8 = (ulong)(_step & 7UL); // % 8
|
||||
_step3 = Mod3(_step);
|
||||
_step5 = Mod5(_step);
|
||||
_step8 = _step.Mod8();
|
||||
_step3 = _step.Mod3();
|
||||
_step5 = _step.Mod5();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
@@ -71,29 +71,6 @@ public sealed class MersenneResidueAutomaton
|
||||
}
|
||||
Mod5R = r5;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static ulong Mod8(UInt128 value) => (ulong)value & 7UL;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static ulong Mod3(UInt128 value)
|
||||
{
|
||||
// 2^64 ≡ 1 (mod 3)
|
||||
ulong high = (ulong)(value >> 64);
|
||||
ulong low = (ulong)value;
|
||||
ulong rem = (low % 3UL) + (high % 3UL);
|
||||
return rem >= 3UL ? rem - 3UL : rem;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static ulong Mod5(UInt128 value)
|
||||
{
|
||||
// 2^64 ≡ 1 (mod 5)
|
||||
ulong high = (ulong)(value >> 64);
|
||||
ulong low = (ulong)value;
|
||||
ulong rem = (low % 5UL) + (high % 5UL);
|
||||
return rem >= 5UL ? rem - 5UL : rem;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -224,7 +224,7 @@ public static class UInt128Extensions
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ulong Mod8(this UInt128 value) => (ulong)value & 7UL;
|
||||
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ulong Mod3(this UInt128 value)
|
||||
{
|
||||
@@ -241,6 +241,7 @@ public static class UInt128Extensions
|
||||
return rem >= 5UL ? rem - 5UL : rem;
|
||||
}
|
||||
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static UInt128 Mul64(this UInt128 a, UInt128 b)
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user