无法创建庞大的数组

Tho*_*oub 11 c# arrays

像许多其他程序员一样,我进入了素数,而且他们中的很多人,我喜欢的是挑战,所以我不是在寻找评论,比如阿特金比你这么做得快,但只是一个解决方案 - 或者至少是一个暗示 - 对我的问题.

我需要创建数组(如size> int.MaxValue).所以我去了很多网页,发现gcAllowVeryLargeObjects元素一个.我以为我得救了,给我加上以下魔法App.config:

<configuration>
  <runtime>
    <gcAllowVeryLargeObjects enabled="true" />
  </runtime>
</configuration>
Run Code Online (Sandbox Code Playgroud)

但它没有奏效.这是我使用的代码:

void go(object sender, EventArgs eventArgs)
{
    t.Stop();
    ulong maxprime = 10;
    Stopwatch stopwatch = new Stopwatch();
    string s = String.Empty;
    while (maxprime < ulong.MaxValue)
    {
        stopwatch.Restart();
        richTextBox2.Text += Environment.NewLine + ("Max \t= " + maxprime.ToString("N0"));
        try
        {
            richTextBox2.Text += Environment.NewLine + ("Count \t= " + GetAllPrimesLessThan(maxprime).Count);
            richTextBox2.Text += Environment.NewLine + ("Time \t= " + stopwatch.Elapsed);
            richTextBox2.Text += Environment.NewLine + ("--------------------------------");
            maxprime *= 10;
            richTextBox2.Refresh();
        }
        catch (Exception exception)
        {
            s = exception.Message + "; Allocation size: " + (maxprime + 1).ToString("N0");
            break;
        }

    }
    if (!string.IsNullOrEmpty(s))
    {
        richTextBox2.Text += Environment.NewLine + s;
    }
    richTextBox2.Text += Environment.NewLine + ("Done.");
}

private static List<ulong> GetAllPrimesLessThan(ulong maxPrime)
{
    var primes = new List<ulong>() { 2 };
    var maxSquareRoot = Math.Sqrt(maxPrime);
    var eliminated = new bool[maxPrime + 1];

    for (ulong i = 3; i <= maxPrime; i += 2)
    {
        if (!eliminated[i])
        {
            primes.Add(i);
            if (i < maxSquareRoot)
            {
                for (ulong j = i * i; j <= maxPrime; j += 2 * i)
                {
                    eliminated[j] = true;
                }
            }
        }
    }
    return primes;
}
Run Code Online (Sandbox Code Playgroud)

哪个输出:

[...]
Max     = 1 000 000 000
Count   = 50847534
Time    = 00:00:15.3355367
--------------------------------
Max     = 10 000 000 000
Array dimensions exceeded supported range.; Allocation size: 10 000 000 001
Done.
Run Code Online (Sandbox Code Playgroud)

我怎样才能摆脱这个错误?


仅供我:我有

  • 16GB内存;
  • SSD上32GB内存映射(/ paged?);
  • 启用了64位

Cod*_*ter 16

从您的链接:

在应用程序配置文件中使用此元素可以启用大小超过2 GB的阵列,但不会更改对象大小或数组大小的其他限制:

对于字节数组和单字节结构数组,任何单个维度的最大索引为2,147,483,591(0x7FFFFFC7),对于其他类型,最大索引为2,146,435,071(0X7FEFFFFF).

另请参见64位Windows上.NET中数组的最大长度是多少:

理论上,一个数组最多可以包含2,147,483,647个元素,因为它使用int进行索引.


Pat*_*man 8

如果达到整数最大范围的范围,则可以选择使用基于long-index的数组.

问题是,这是不被支持的C#索引器性能,它使用int.您可以通过使用手动构建它们Array.CreateInstance(Type, long[]).

请注意,您必须使用值Array.GetValue(long).

  • `Array.CreateInstance(typeof(int),Int32.MaxValue)`在64位上抛出`OutOfMemoryException`,`Array.CreateInstance(typeof(int),UInt32.MaxValue)`throws _"不支持大于2GB的数组"_即使启用了`gcAllowVeryLargeObjects`设置...(.NET 4.5.3). (6认同)