Cache composite primality results in PartialFactor

This commit is contained in:
Marek Lemańczyk committed 2025-10-19 22:49:38 +02:00
1 parent 324080d265
commit 627d2e9b14
2 files changed
+71 -3

No files matched your search

@@ -757,6 +757,27 @@ internal static partial class PrimeOrderCalculator
Stack<ulong>? compositeStack = null;
PartialFactorResult result;
Dictionary<ulong, bool>? localPrimalityCache = null;
bool EvaluatePrimality(ulong candidate)
{
Dictionary<ulong, bool>? cache = localPrimalityCache;
if (cache is not null && cache.TryGetValue(candidate, out bool cachedValue))
{
return cachedValue;
}
bool computed = GetOrComputePrimality(candidate);
if (!computed)
{
cache ??= ThreadStaticPools.RentUlongBoolDictionary(4);
cache[candidate] = false;
localPrimalityCache = cache;
}
return computed;
}
if (!gpuFactored)
{
// We don't need to worry about leftovers, because we always use indexes within the calculated counts
@@ -821,7 +842,7 @@ internal static partial class PrimeOrderCalculator
// continue;
// }
bool isPrime = GetOrComputePrimality(composite);
bool isPrime = EvaluatePrimality(composite);
if (isPrime)
{
@@ -868,7 +889,7 @@ internal static partial class PrimeOrderCalculator
continue;
}
bool isPrime = GetOrComputePrimality(composite);
bool isPrime = EvaluatePrimality(composite);
if (isPrime)
{
@@ -894,7 +915,7 @@ internal static partial class PrimeOrderCalculator
}
else
{
cofactorIsPrime = GetOrComputePrimality(cofactor);
cofactorIsPrime = EvaluatePrimality(cofactor);
}
ArrayPool<FactorEntry> pool = ThreadStaticPools.FactorEntryPool;
@@ -968,6 +989,11 @@ internal static partial class PrimeOrderCalculator
// ThreadStaticPools.UlongPool.Return(primeSlotsArray);
// ThreadStaticPools.IntPool.Return(exponentSlotsArray);
if (localPrimalityCache is not null)
{
ThreadStaticPools.ReturnUlongBoolDictionary(localPrimalityCache);
}
if (counts is not null)
{
ThreadStaticPools.ReturnUlongIntDictionary(counts);
+42
View File
@@ -278,6 +278,48 @@ namespace PerfectNumbers.Core
pool.Add(dictionary);
}
[ThreadStatic]
private static List<Dictionary<ulong, bool>>? _ulongBoolDictionaryPool;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Dictionary<ulong, bool> RentUlongBoolDictionary(int capacityHint)
{
List<Dictionary<ulong, bool>>? pool = _ulongBoolDictionaryPool;
if (pool is not null && pool.Count > 0)
{
int lastIndex = pool.Count - 1;
Dictionary<ulong, bool> dictionary = pool[lastIndex];
pool.RemoveAt(lastIndex);
if (dictionary.Count > 0)
{
dictionary.Clear();
}
if (dictionary.Count < capacityHint)
{
dictionary.EnsureCapacity(capacityHint);
}
return dictionary;
}
return new Dictionary<ulong, bool>(capacityHint);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ReturnUlongBoolDictionary(Dictionary<ulong, bool> dictionary)
{
List<Dictionary<ulong, bool>>? pool = _ulongBoolDictionaryPool;
if (pool is null)
{
pool = new List<Dictionary<ulong, bool>>(4);
_ulongBoolDictionaryPool = pool;
}
dictionary.Clear();
pool.Add(dictionary);
}
[ThreadStatic]
private static Dictionary<ulong, MersenneDivisorCycles.FactorCacheEntry>? _mersenneFactorCacheDictionary;