我需要在C#中使用非常大的数组长度(大小)

时间:2013-10-24 21:47:38

标签: c# arrays size biginteger

public double[] result = new double[ ??? ];

我存储的结果和结果的总数大于2,147,483,647,即max int32。

我尝试过biginteger,ulong等,但他们都给了我错误。

如何扩展可以存储>的数组的大小?里面有50,147,483,647个结果(双)吗?

...谢谢

5 个答案:

答案 0 :(得分:11)

2,147,483,648 double的数组将占用16GB的内存。对某些人来说,这不是什么大不了的事。我有服务器,如果我分配一些这些数组,甚至不会打扰页面文件。并不意味着这是一个好主意。

当您处理大量数据时,您应该考虑尽量减少流程对内存的影响。有几种方法可以解决这个问题,具体取决于您处理数据的方式。


稀疏数组

如果您的数组是稀疏填充的 - 许多默认/空值以及实际有效/有用数据的百分比很小 - 那么稀疏数组可以大大减少内存需求。您可以编写各种实现来针对不同的分布配置文件进行优化:随机分布,分组值,任意连续组等。

适用于任何类型的包含数据,包括复杂类。有一些开销,所以当填充百分比很高时,实际上可能比裸阵列更糟糕。当然,你仍然会使用内存来存储你的实际数据。

简单平面文件

将数据存储在磁盘上,为文件创建读/写FileStream,并将其封装在一个包装器中,使您可以像访问内存数组一样访问文件的内容。最简单的实现将为您提供从文件顺序读取的合理用途。随机读取和写入可能会降低您的速度,但您可以在后台执行一些缓冲以帮助缓解速度问题。

此方法适用于任何具有静态大小的类型,包括可以复制到文件中的一系列字节的结构。对于像字符串这样的动态大小的数据不起作用。

复杂平面文件

如果您需要处理动态大小的记录,稀疏数据等,那么您可以设计一种可以优雅地处理它的文件格式。然后,数据库可能是更好的选择。

内存映射文件

与其他文件选项相同,但使用不同的机制来访问数据。有关如何使用.NET中的内存映射文件的详细信息,请参阅System.IO.MemoryMappedFile

数据库存储

根据数据的性质,将其存储在数据库中可能对您有用。对于大量double s,这不太可能是一个很好的选择。在数据库中读取/写入数据的开销加上存储开销 - 每行至少需要有一个行标识,对于大型记录集可能是BIG_INT(8字节整数),加倍蝙蝠的数据大小。添加索引,行存储等开销,您可以非常轻松地将数据大小相乘。

数据库非常适合存储和处理复杂数据。这就是他们的目的。如果你有可变宽度的数据 - 字符串之类 - 那么数据库可能是你最好的选择之一。另一方面,它们通常不是处理大量非常简单数据的最佳解决方案。


无论您选择哪种方式,都可以创建一个封装数据的IList<T>兼容类。这使您可以编写无需知道如何存储数据的代码,只需编写 的内容。

答案 1 :(得分:5)

BCL阵列无法做到这一点 有人写了一个可以的BigArray<T> class分块。

然而,这不会神奇地创造足够的内存来存储它。

答案 2 :(得分:2)

你做不到。即使使用gcAllowVeryLargeObjects,数组中任何维度(非byte s)的最大大小为2,146,435,071

因此,您需要重新考虑您的设计,或使用其他实现,例如锯齿状阵列。

答案 3 :(得分:0)

另一种可能的方法是实现自己的BigList。首先请注意,List是作为一个数组实现的。此外,您可以在构造函数中设置List的初始大小,因此如果您知道它会很大,请预先获得大量内存。

然后

public class myBigList<T> : List<List<T>>
{

}

或者,更可取的是,使用has-a方法:

public class myBigList<T>
{
   List<List<T>> theList;
}

在执行此操作时,您需要重新实现索引器,以便可以使用除法和模数在后备存储中查找正确的索引。然后,您可以使用BigInt作为索引。在自定义索引器中,您将BigInt分解为两个合法大小的整数。

答案 4 :(得分:-3)

C#数组的大小限制为System.Int32.MaxValue

如果大于此值,请使用List<T>(其中T是您想要保留的任何内容)。

更多信息:What is the Maximum Size that an Array can hold?