为啥 C# 数组仍然限制在约 21 亿个元素中

Posted

技术标签:

【中文标题】为啥 C# 数组仍然限制在约 21 亿个元素中【英文标题】:Why are C# arrays still limited to ~2.1 billion elements为什么 C# 数组仍然限制在约 21 亿个元素中 【发布时间】:2019-09-04 17:11:22 【问题描述】:

.Net 4.5 gcAllowVeryLargeObjects 被引入以允许 64 位系统的大小大于 2gb 的数组。然而,数组曾经(并且仍然)被限制在大约 42 亿个元素和大约 21 亿个维度中。为什么?

对它没有兴趣,还是存在阻止他们在 .Net 核心类(数组、列表等)中使用字长索引器的实际问题?

C# 已经允许在自定义类中使用长类型索引器,并且将索引器从 int 更改为 long 以用于 64 位构建将不会中断(我相信),因为 int 始终可以转换为 long。

【问题讨论】:

将类型更改为long 将是一项重大更改,因为long 无法分配给int 我认为如果你有这么大的对象,那么使用编译语言而不是 C# 在 SIMD 中工作可能会更好 @Lee 但如果索引器很长,则分配是从 int 到 long(非中断)。我当然可以理解,如果将来的代码是为 64 位编写的,那么如果编译为 32 位,它可能有一天会被破坏。问题变成了 C# 未来的预期架构和用途。 @phuclv C# 内置了 SIMD 操作,并支持将它们扩展到自定义算法。我在这里尝试完成的是记忆动态规划问题。 如果您有int i = someArray.Length 并将Length 的类型更改为long,则此代码将中断。无论目标架构如何,ints 始终为 32 位,因此编译为 64 位架构不会有任何区别。有一个 [LongLength](docs.microsoft.com/en-us/dotnet/api/…) 属性返回一个long 【参考方案1】:

因为数组索引是整数,而C#中的int类型有最大值。

【讨论】:

虽然这可以回答问题,但后续问题非常简单:为什么数组索引是ints 而不是longs 你有没有读过标题?问题是为什么在构建 64 位时它必须是整数。 请注意,如果您有一个数组 double[],那么您将获得 8 字节 * 42 亿个元素 = 336 亿字节 = 32 GB 的最大字节大小。这超过 2GB。 @OlivierJacot-Descombes 如果您没有启用 gcAllowVeryLargeObjects,您甚至不会走那么远。您将在 2gb 处引发异常。

以上是关于为啥 C# 数组仍然限制在约 21 亿个元素中的主要内容,如果未能解决你的问题,请参考以下文章

c#用foreach遍历数组、列表时是直接获得数据元素,而foreach哈希表时,为啥获得的是命名空间名??

每次绘制 C# 删除数组元素

C#将数组的元素添加到循环内的列表中

c#查找最长连续子数组第一个和最后一个元素索引

为啥我应该“将 myVariable 转换为最终的一个元素数组”?

为啥我的 for 循环只读取我创建的数组的最后一个元素? [复制]