From b81fe3de75f373b897c7ff5d905efd8c538d78cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Lema=C5=84czyk?= Date: Fri, 17 Oct 2025 01:14:51 +0200 Subject: [PATCH] Hoist Pollard Rho deadline checks outside factoring loop --- PerfectNumbers.Core/PrimeOrderCalculator.cs | 68 +++++++++++---------- 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/PerfectNumbers.Core/PrimeOrderCalculator.cs b/PerfectNumbers.Core/PrimeOrderCalculator.cs index 9ead71b..662b3d6 100644 --- a/PerfectNumbers.Core/PrimeOrderCalculator.cs +++ b/PerfectNumbers.Core/PrimeOrderCalculator.cs @@ -852,44 +852,50 @@ internal static partial class PrimeOrderCalculator compositeStack.Push(remaining); pending.Clear(); - long timestamp = 0L; - while (compositeStack.Count > 0) + bool pollardRhoDeadlineReached = Stopwatch.GetTimestamp() > deadlineTimestamp; + if (!pollardRhoDeadlineReached) { - ulong composite = compositeStack.Pop(); - // composite will never be smaller than 1 on the execution path - // if (composite <= 1UL) - // { - // continue; - // } - - if (!cache.TryGetValue(composite, out bool isPrime)) + while (compositeStack.Count > 0) { - isPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(composite); - cache.Add(composite, isPrime); + ulong composite = compositeStack.Pop(); + // composite will never be smaller than 1 on the execution path + // if (composite <= 1UL) + // { + // continue; + // } + + if (!cache.TryGetValue(composite, out bool isPrime)) + { + isPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(composite); + cache.Add(composite, isPrime); + } + + if (isPrime) + { + AddFactorToCollector(ref useDictionary, ref counts, primeSlots, exponentSlots, ref factorCount, composite, 1); + continue; + } + + if (!TryPollardRho(composite, deadlineTimestamp, out ulong factor)) + { + pending.Add(composite); + continue; + } + + ulong quotient = composite / factor; + compositeStack.Push(factor); + compositeStack.Push(quotient); } - if (isPrime) - { - AddFactorToCollector(ref useDictionary, ref counts, primeSlots, exponentSlots, ref factorCount, composite, 1); - continue; - } + pollardRhoDeadlineReached = Stopwatch.GetTimestamp() > deadlineTimestamp; + } - timestamp = Stopwatch.GetTimestamp(); - if (timestamp > deadlineTimestamp) + if (pollardRhoDeadlineReached) + { + while (compositeStack.Count > 0) { - pending.Add(composite); - continue; + pending.Add(compositeStack.Pop()); } - - if (!TryPollardRho(composite, deadlineTimestamp, out ulong factor)) - { - pending.Add(composite); - continue; - } - - ulong quotient = composite / factor; - compositeStack.Push(factor); - compositeStack.Push(quotient); } }