Refine partial factor primality caching
This commit is contained in:
1 parent
0fbd635828
commit
43e2894661
2 files changed
+34
-15
No files matched your search
@@ -730,7 +730,8 @@ internal static partial class PrimeOrderCalculator
|
|||||||
}
|
}
|
||||||
|
|
||||||
ulong globalCacheLimit = (ulong)PerfectNumberConstants.MaxQForDivisorCycles;
|
ulong globalCacheLimit = (ulong)PerfectNumberConstants.MaxQForDivisorCycles;
|
||||||
if (candidate > globalCacheLimit)
|
bool bypassesGlobalCache = candidate > globalCacheLimit;
|
||||||
|
if (bypassesGlobalCache)
|
||||||
{
|
{
|
||||||
Dictionary<ulong, bool>? cache = localCache;
|
Dictionary<ulong, bool>? cache = localCache;
|
||||||
if (cache is not null && cache.TryGetValue(candidate, out bool cachedValue))
|
if (cache is not null && cache.TryGetValue(candidate, out bool cachedValue))
|
||||||
@@ -742,12 +743,13 @@ internal static partial class PrimeOrderCalculator
|
|||||||
bool isPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(candidate);
|
bool isPrime = Open.Numeric.Primes.Prime.Numbers.IsPrime(candidate);
|
||||||
CachePrimalityResult(candidate, isPrime);
|
CachePrimalityResult(candidate, isPrime);
|
||||||
|
|
||||||
if (candidate > globalCacheLimit)
|
if (bypassesGlobalCache)
|
||||||
{
|
{
|
||||||
Dictionary<ulong, bool>? cache = localCache;
|
Dictionary<ulong, bool>? cache = localCache;
|
||||||
if (cache is null)
|
if (cache is null)
|
||||||
{
|
{
|
||||||
cache = ThreadStaticPools.RentUlongBoolDictionary(4);
|
cache = ThreadStaticPools.RentUlongBoolDictionary(4);
|
||||||
|
cache.Clear();
|
||||||
localCache = cache;
|
localCache = cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -279,22 +279,39 @@ namespace PerfectNumbers.Core
|
|||||||
}
|
}
|
||||||
|
|
||||||
[ThreadStatic]
|
[ThreadStatic]
|
||||||
private static List<Dictionary<ulong, bool>>? _ulongBoolDictionaryPool;
|
private static Stack<Dictionary<ulong, bool>>? _ulongBoolDictionaryPool;
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static Dictionary<ulong, bool> RentUlongBoolDictionary(int capacityHint)
|
public static Dictionary<ulong, bool> RentUlongBoolDictionary(int capacityHint)
|
||||||
{
|
{
|
||||||
List<Dictionary<ulong, bool>>? pool = _ulongBoolDictionaryPool;
|
Stack<Dictionary<ulong, bool>>? pool = _ulongBoolDictionaryPool;
|
||||||
if (pool is not null && pool.Count > 0)
|
if (pool is null)
|
||||||
{
|
{
|
||||||
int lastIndex = pool.Count - 1;
|
pool = new Stack<Dictionary<ulong, bool>>(4);
|
||||||
Dictionary<ulong, bool> dictionary = pool[lastIndex];
|
_ulongBoolDictionaryPool = pool;
|
||||||
pool.RemoveAt(lastIndex);
|
|
||||||
if (dictionary.Count > 0)
|
|
||||||
{
|
|
||||||
dictionary.Clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Keep the previous null-check implementation here for reference.
|
||||||
|
// Do not uncomment this branch; the pool is always initialized above.
|
||||||
|
// if (pool is not null && pool.Count > 0)
|
||||||
|
// {
|
||||||
|
// Dictionary<ulong, bool> dictionary = pool.Pop();
|
||||||
|
// if (dictionary.Count < capacityHint)
|
||||||
|
// {
|
||||||
|
// dictionary.EnsureCapacity(capacityHint);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return dictionary;
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (pool.Count > 0)
|
||||||
|
{
|
||||||
|
Dictionary<ulong, bool> dictionary = pool.Pop();
|
||||||
|
// Callers clear dictionaries after renting to avoid duplicate work.
|
||||||
|
// if (dictionary.Count > 0)
|
||||||
|
// {
|
||||||
|
// dictionary.Clear();
|
||||||
|
// }
|
||||||
if (dictionary.Count < capacityHint)
|
if (dictionary.Count < capacityHint)
|
||||||
{
|
{
|
||||||
dictionary.EnsureCapacity(capacityHint);
|
dictionary.EnsureCapacity(capacityHint);
|
||||||
@@ -309,15 +326,15 @@ namespace PerfectNumbers.Core
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static void ReturnUlongBoolDictionary(Dictionary<ulong, bool> dictionary)
|
public static void ReturnUlongBoolDictionary(Dictionary<ulong, bool> dictionary)
|
||||||
{
|
{
|
||||||
List<Dictionary<ulong, bool>>? pool = _ulongBoolDictionaryPool;
|
Stack<Dictionary<ulong, bool>>? pool = _ulongBoolDictionaryPool;
|
||||||
if (pool is null)
|
if (pool is null)
|
||||||
{
|
{
|
||||||
pool = new List<Dictionary<ulong, bool>>(4);
|
pool = new Stack<Dictionary<ulong, bool>>(4);
|
||||||
_ulongBoolDictionaryPool = pool;
|
_ulongBoolDictionaryPool = pool;
|
||||||
}
|
}
|
||||||
|
|
||||||
dictionary.Clear();
|
// Do not clear pooled dictionaries here; callers must clear on rent.
|
||||||
pool.Add(dictionary);
|
pool.Push(dictionary);
|
||||||
}
|
}
|
||||||
|
|
||||||
[ThreadStatic]
|
[ThreadStatic]
|
||||||
|
|||||||
Reference in new issue
Block a user