您根本不需要那么大的数组。
当你的方法遇到资源问题时,不要只看如何扩展资源,还要看方法。:)
这是一个使用 3 MB 缓冲区来使用 Eratosthenes 筛计算素数的类。该类跟踪您计算质数的距离,以及何时需要扩展范围,它会创建一个缓冲区来测试另外 300 万个数字。
它将找到的素数保存在一个列表中,当范围扩大时,previos 素数用于排除缓冲区中的数字。
我做了一些测试,大约 3 MB 的缓冲区是最有效的。
public class Primes {
private const int _blockSize = 3000000;
private List<long> _primes;
private long _next;
public Primes() {
_primes = new List<long>() { 2, 3, 5, 7, 11, 13, 17, 19 };
_next = 23;
}
private void Expand() {
bool[] sieve = new bool[_blockSize];
foreach (long prime in _primes) {
for (long i = ((_next + prime - 1L) / prime) * prime - _next;
i < _blockSize; i += prime) {
sieve[i] = true;
}
}
for (int i = 0; i < _blockSize; i++) {
if (!sieve[i]) {
_primes.Add(_next);
for (long j = i + _next; j < _blockSize; j += _next) {
sieve[j] = true;
}
}
_next++;
}
}
public long this[int index] {
get {
if (index < 0) throw new IndexOutOfRangeException();
while (index >= _primes.Count) {
Expand();
}
return _primes[index];
}
}
public bool IsPrime(long number) {
while (_primes[_primes.Count - 1] < number) {
Expand();
}
return _primes.BinarySearch(number) >= 0;
}
}