Optimize filtering strategy for previous Mersenne results
This commit is contained in:
1 parent
77cc1fc280
commit
e1d4bbf12d
1 file changed
+50
-23
@@ -38,34 +38,65 @@ public static class MersenneNumberDivisorByDivisorTester
|
|||||||
if (previousResults is not null && previousResults.Count > 0)
|
if (previousResults is not null && previousResults.Count > 0)
|
||||||
{
|
{
|
||||||
int recordedCount = previousResults.Count;
|
int recordedCount = previousResults.Count;
|
||||||
ulong[] recordedCandidates = ArrayPool<ulong>.Shared.Rent(recordedCount);
|
bool preferSortedMerge = recordedCount <= 4096 || (recordedCount * 4L) <= candidateCount;
|
||||||
try
|
if (preferSortedMerge)
|
||||||
{
|
{
|
||||||
Span<ulong> recordedSpan = recordedCandidates.AsSpan(0, recordedCount);
|
ulong[] recordedCandidates = ArrayPool<ulong>.Shared.Rent(recordedCount);
|
||||||
int recordedIndex = 0;
|
try
|
||||||
foreach (ulong value in previousResults.Keys)
|
|
||||||
{
|
{
|
||||||
recordedSpan[recordedIndex++] = value;
|
Span<ulong> recordedSpan = recordedCandidates.AsSpan(0, recordedCount);
|
||||||
|
int recordedIndex = 0;
|
||||||
|
foreach (ulong value in previousResults.Keys)
|
||||||
|
{
|
||||||
|
recordedSpan[recordedIndex++] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
recordedSpan.Sort();
|
||||||
|
|
||||||
|
int writeIndex = 0;
|
||||||
|
int skipIndex = 0;
|
||||||
|
|
||||||
|
for (int readIndex = 0; readIndex < candidateCount; readIndex++)
|
||||||
|
{
|
||||||
|
ulong candidate = candidateSpan[readIndex];
|
||||||
|
|
||||||
|
while (skipIndex < recordedCount && recordedSpan[skipIndex] < candidate)
|
||||||
|
{
|
||||||
|
skipIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (skipIndex < recordedCount && recordedSpan[skipIndex] == candidate)
|
||||||
|
{
|
||||||
|
skippedByPreviousResults++;
|
||||||
|
skipIndex++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
candidateSpan[writeIndex++] = candidate;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (writeIndex < candidateCount)
|
||||||
|
{
|
||||||
|
candidates.RemoveRange(writeIndex, candidateCount - writeIndex);
|
||||||
|
candidateSpan = CollectionsMarshal.AsSpan(candidates); // candidateSpan now tracks the reduced list.
|
||||||
|
candidateCount = candidateSpan.Length;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
recordedSpan.Sort();
|
{
|
||||||
|
ArrayPool<ulong>.Shared.Return(recordedCandidates, clearArray: true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
int writeIndex = 0;
|
int writeIndex = 0;
|
||||||
int skipIndex = 0;
|
|
||||||
|
|
||||||
for (int readIndex = 0; readIndex < candidateCount; readIndex++)
|
for (int readIndex = 0; readIndex < candidateCount; readIndex++)
|
||||||
{
|
{
|
||||||
ulong candidate = candidateSpan[readIndex];
|
ulong candidate = candidateSpan[readIndex];
|
||||||
|
|
||||||
while (skipIndex < recordedCount && recordedSpan[skipIndex] < candidate)
|
if (previousResults.ContainsKey(candidate))
|
||||||
{
|
|
||||||
skipIndex++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (skipIndex < recordedCount && recordedSpan[skipIndex] == candidate)
|
|
||||||
{
|
{
|
||||||
skippedByPreviousResults++;
|
skippedByPreviousResults++;
|
||||||
skipIndex++;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,14 +106,10 @@ public static class MersenneNumberDivisorByDivisorTester
|
|||||||
if (writeIndex < candidateCount)
|
if (writeIndex < candidateCount)
|
||||||
{
|
{
|
||||||
candidates.RemoveRange(writeIndex, candidateCount - writeIndex);
|
candidates.RemoveRange(writeIndex, candidateCount - writeIndex);
|
||||||
candidateSpan = CollectionsMarshal.AsSpan(candidates);
|
candidateSpan = CollectionsMarshal.AsSpan(candidates); // candidateSpan now tracks the reduced list.
|
||||||
candidateCount = candidateSpan.Length;
|
candidateCount = candidateSpan.Length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
|
||||||
ArrayPool<ulong>.Shared.Return(recordedCandidates, clearArray: true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (skippedByPreviousResults > 0)
|
if (skippedByPreviousResults > 0)
|
||||||
|
|||||||
Reference in new issue
Block a user