Cache composite primality results in PartialFactor
This commit is contained in:
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;
|
Stack<ulong>? compositeStack = null;
|
||||||
PartialFactorResult result;
|
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)
|
if (!gpuFactored)
|
||||||
{
|
{
|
||||||
// We don't need to worry about leftovers, because we always use indexes within the calculated counts
|
// 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;
|
// continue;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
bool isPrime = GetOrComputePrimality(composite);
|
bool isPrime = EvaluatePrimality(composite);
|
||||||
|
|
||||||
if (isPrime)
|
if (isPrime)
|
||||||
{
|
{
|
||||||
@@ -868,7 +889,7 @@ internal static partial class PrimeOrderCalculator
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isPrime = GetOrComputePrimality(composite);
|
bool isPrime = EvaluatePrimality(composite);
|
||||||
|
|
||||||
if (isPrime)
|
if (isPrime)
|
||||||
{
|
{
|
||||||
@@ -894,7 +915,7 @@ internal static partial class PrimeOrderCalculator
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cofactorIsPrime = GetOrComputePrimality(cofactor);
|
cofactorIsPrime = EvaluatePrimality(cofactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayPool<FactorEntry> pool = ThreadStaticPools.FactorEntryPool;
|
ArrayPool<FactorEntry> pool = ThreadStaticPools.FactorEntryPool;
|
||||||
@@ -968,6 +989,11 @@ internal static partial class PrimeOrderCalculator
|
|||||||
// ThreadStaticPools.UlongPool.Return(primeSlotsArray);
|
// ThreadStaticPools.UlongPool.Return(primeSlotsArray);
|
||||||
// ThreadStaticPools.IntPool.Return(exponentSlotsArray);
|
// ThreadStaticPools.IntPool.Return(exponentSlotsArray);
|
||||||
|
|
||||||
|
if (localPrimalityCache is not null)
|
||||||
|
{
|
||||||
|
ThreadStaticPools.ReturnUlongBoolDictionary(localPrimalityCache);
|
||||||
|
}
|
||||||
|
|
||||||
if (counts is not null)
|
if (counts is not null)
|
||||||
{
|
{
|
||||||
ThreadStaticPools.ReturnUlongIntDictionary(counts);
|
ThreadStaticPools.ReturnUlongIntDictionary(counts);
|
||||||
|
|||||||
@@ -278,6 +278,48 @@ namespace PerfectNumbers.Core
|
|||||||
pool.Add(dictionary);
|
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]
|
[ThreadStatic]
|
||||||
private static Dictionary<ulong, MersenneDivisorCycles.FactorCacheEntry>? _mersenneFactorCacheDictionary;
|
private static Dictionary<ulong, MersenneDivisorCycles.FactorCacheEntry>? _mersenneFactorCacheDictionary;
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user