在 C# 中处理大型数据数组的最有效方法?
Most efficient way to handle large arrays of data in C#?
目前我正在使用带有 C# Visual Studio 2010 的 XNA Game Studio 4.0。我想使用一种通用的方法来处理三角形。我正在使用通过 GraphicsDevice.DrawUserPrimitives() 方法传递的 VertexPositionColor 项的预设数组,该方法仅处理数组。因为数组是固定的,但是我想有一个非常大的space来任意添加新的三角形到数组中,我最初的想法是做一个大数组,具体是
VertexPositionColor vertices = new VertexPositionColor[int.MaxValue];
但是 运行 我的应用程序内存不足。所以我想知道如何最好地解决这个 memory/performance 问题。
- 有没有一种简单的方法可以在我的程序运行时增加分配给堆栈的内存量?
- 将数组存储在堆上是否有益?如果我想这样做,我是否必须构建自己的分配器?
- 或者我最好的方法是简单地使用 LinkedList 并处理将其每帧复制到数组所需的额外处理?
我用这个构建了我的体素引擎代码。
想想我遇到的问题:
给定一个明显大于计算机内存量的未知卷大小,我该如何管理该数据量?
我的解决方案是使用稀疏分块。例如:
在我的例子中,我没有使用数组,而是使用了字典。
这样我就可以根据一个键来查找值,这个键就是体素位置的哈希码,而这个值就是体素本身。
这意味着体素可以快速提取,并由语言/编译器自行组织到一个索引集中。
这也意味着当提取数据时,我可以为尚未分配的体素默认 Voxel.Empty。
在您的情况下,您可能不需要默认值,但使用字典可能比数组更有用。
向上镜头...数组在某些方面稍快一些,但当您考虑数据的所有使用场景时,您可能会发现使用字典的总体收益值得少量分配成本。
在测试中,我发现如果我准备好在分配上从每千分之 100 毫秒下降到每千分之 120 毫秒,那么对于我在集合上执行的大多数查询,我可以更快地检索数据 100%。
我在这里提出建议的原因:
看起来您不知道数据集的大小,只有在知道大小的情况下使用数组才有意义,否则您会无缘无故地占用 "pre allocated chunks of ram" 来使您的代码已准备好应对任何可能发生的情况。
希望对您有所帮助。
你可以试试List<T>
和ToArray()
方法关联List。 XNA 框架也支持它 (MSDN)。
List
是 ArrayList
的继承者,提供了更多的功能和 strongly typed
(很好的 comparison)。
关于性能,List<T>.ToArray
是一个O(n) operation
。我建议您将冗长的数组拆分为您可以使用 key
[某个区域的某种唯一标识符等] 命名的部分。并将相关信息存储在List
中并使用Dictionary
像Dictionary<Key, List<T>>
这样可以减少涉及的操作。您还可以使用基于优先级的方法处理所需的模型,这将比一次处理完成 array
获得性能提升。
目前我正在使用带有 C# Visual Studio 2010 的 XNA Game Studio 4.0。我想使用一种通用的方法来处理三角形。我正在使用通过 GraphicsDevice.DrawUserPrimitives() 方法传递的 VertexPositionColor 项的预设数组,该方法仅处理数组。因为数组是固定的,但是我想有一个非常大的space来任意添加新的三角形到数组中,我最初的想法是做一个大数组,具体是
VertexPositionColor vertices = new VertexPositionColor[int.MaxValue];
但是 运行 我的应用程序内存不足。所以我想知道如何最好地解决这个 memory/performance 问题。
- 有没有一种简单的方法可以在我的程序运行时增加分配给堆栈的内存量?
- 将数组存储在堆上是否有益?如果我想这样做,我是否必须构建自己的分配器?
- 或者我最好的方法是简单地使用 LinkedList 并处理将其每帧复制到数组所需的额外处理?
我用这个构建了我的体素引擎代码。 想想我遇到的问题:
给定一个明显大于计算机内存量的未知卷大小,我该如何管理该数据量?
我的解决方案是使用稀疏分块。例如:
在我的例子中,我没有使用数组,而是使用了字典。 这样我就可以根据一个键来查找值,这个键就是体素位置的哈希码,而这个值就是体素本身。 这意味着体素可以快速提取,并由语言/编译器自行组织到一个索引集中。
这也意味着当提取数据时,我可以为尚未分配的体素默认 Voxel.Empty。
在您的情况下,您可能不需要默认值,但使用字典可能比数组更有用。
向上镜头...数组在某些方面稍快一些,但当您考虑数据的所有使用场景时,您可能会发现使用字典的总体收益值得少量分配成本。
在测试中,我发现如果我准备好在分配上从每千分之 100 毫秒下降到每千分之 120 毫秒,那么对于我在集合上执行的大多数查询,我可以更快地检索数据 100%。
我在这里提出建议的原因:
看起来您不知道数据集的大小,只有在知道大小的情况下使用数组才有意义,否则您会无缘无故地占用 "pre allocated chunks of ram" 来使您的代码已准备好应对任何可能发生的情况。
希望对您有所帮助。
你可以试试List<T>
和ToArray()
方法关联List。 XNA 框架也支持它 (MSDN)。
List
是 ArrayList
的继承者,提供了更多的功能和 strongly typed
(很好的 comparison)。
关于性能,List<T>.ToArray
是一个O(n) operation
。我建议您将冗长的数组拆分为您可以使用 key
[某个区域的某种唯一标识符等] 命名的部分。并将相关信息存储在List
中并使用Dictionary
像Dictionary<Key, List<T>>
这样可以减少涉及的操作。您还可以使用基于优先级的方法处理所需的模型,这将比一次处理完成 array
获得性能提升。