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

本文关键字:数组 大小 非常 | 更新日期: 2023-09-27 18:36:44

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

我正在存储结果,结果总数大于最大 int32 的 2,147,483,647。

尝试了biginteger,ulong等,但所有这些都给了我错误。

如何扩展可以在其中存储 50,147,483,647 个结果(双精度)>数组的大小?

谢谢。。。

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

2,147,483,648 double 的数组将占用 16GB 的内存。 对于某些人来说,这没什么大不了的。 我的服务器如果我分配了其中的一些数组,它们甚至不会费心点击页面文件。 并不意味着这是一个好主意。

当您处理此类大量数据时,您应该寻求最小化进程的内存影响。 有几种方法可以做到这一点,具体取决于您处理数据的方式。

<小时 />

稀疏数组

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

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

简单平面文件

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

此方法适用于具有静态大小的任何类型,包括可以复制到文件中的字节范围/从文件中的字节范围复制的结构。 不适用于字符串等动态大小的数据。

复杂平面文件

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

内存映射文件

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

数据库存储

根据数据的性质,将其存储在数据库中可能适合您。 然而,对于大量的double来说,这不太可能是一个不错的选择。 在数据库中读取/写入数据的开销,加上存储开销 - 每行至少需要有一个行标识,对于大型记录集来说可能是一个BIG_INT(8 字节整数),使数据的大小立即翻倍。 加上索引、行存储等的开销,您可以非常轻松地增加数据的大小。

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

<小时 />

无论使用哪个选项,都可以创建一个IList<T>兼容的类来封装数据。 这使您可以编写不需要知道数据如何存储的代码,只需要知道数据是什么

BCL 数组无法做到这一点。
有人写了一个可以分块的BigArray<T>类。

但是,这不会神奇地创建足够的内存来存储它。

你不能。即使有gcAllowVeryLargeObjects,数组中任何维度(非byte)的最大大小也是2,146,435,071

因此,您需要重新考虑您的设计,或使用替代实现,例如交错数组。

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

然后

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

或者,也许更可取的是,使用 HAS-A 方法:

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

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

我遇到了同样的问题。我使用列表列表解决了它,该列表很好地模仿了数组,但可以远远超出 2Gb 限制。Ex List它适用于在 32Gb 计算机上运行的 250k x 250k 字节,即使这头大象代表 60Gb+ 空间:-)

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

对于大于此值,请使用List<T>(其中 T 是您想要持有的任何内容)。

更多内容:数组可以容纳的最大大小是多少?