简体   繁体   English

处理C#中大型数据数组的最有效方法?

[英]Most efficient way to handle large arrays of data in C#?

Currently I am using XNA Game Studio 4.0 with C# Visual Studio 2010. I want to use a versatile method for handling triangles. 当前,我将XNA Game Studio 4.0与C#Visual Studio 2010一起使用。我想使用一种通用的方法来处理三角形。 I am using a preset array of VertexPositionColor items passed through the GraphicsDevice.DrawUserPrimitives() method, which only handles arrays. 我正在使用通过GraphicsDevice.DrawUserPrimitives()方法传递的VertexPositionColor项的预设数组,该方法仅处理数组。 Because arrays are fixed, but I wanted to have a very large space to arbitrarily add new triangles to the array, my original idea was to make a large array, specifically 因为数组是固定的,但是我想有一个很大的空间可以向数组中任意添加新的三角形,所以我最初的想法是制作一个大数组,特别是

VertexPositionColor vertices = new VertexPositionColor[int.MaxValue];

but that ran my application out of memory. 但这使我的应用程序内存不足。 So what I'm wondering is how to approach this memory/performance issue best. 因此,我想知道的是如何最好地解决此内存/性能问题。

  • Is there an easy way to increase the amount of memory allocated to the stack whenever my program runs? 每当我的程序运行时,是否有一种简单的方法来增加分配给堆栈的内存量?
  • Would it be beneficial to store the array on the heap instead? 而是将数组存储在堆上是否有益? And would I have to build my own allocator if I wanted to do that? 如果我想这样做,是否必须构建自己的分配器?
  • Or is my best approach simply to use a LinkedList and deal with the extra processing required to copy it to an array every frame? 还是我最好的方法仅仅是使用LinkedList并处理将其每帧复制到数组所需的额外处理?

I hit this building my voxel engine code. 我按此步骤构建了我的体素引擎代码。 Consider the problem I had: 考虑一下我遇到的问题:

Given an unknown volume size that would clearly be bigger than the amount of memory the computer had how do I manage that volume of data? 给定一个未知的卷大小,该大小显然会大于计算机拥有的内存量,我该如何管理该数据量?

My solution was to use sparse chunking. 我的解决方案是使用稀疏分块。 for example: 例如:

In my case instead of using an array I used a dictionary. 就我而言,我没有使用数组,而是使用了字典。 This way I could lookup the values based on a key that was say the hashcode of a voxels position and the value was the voxel itself. 这样,我可以根据一个键(即体素位置的哈希码)来查找值,而该值就是体素本身。 This meant that the voxels were fast to pull out, and self organised by the language / compiler in to an indexed set. 这意味着体素可以快速拉出,并且由语言/编译器自组织成索引集。

It also means that when pulling data back out I could default to Voxel.Empty for voxels that hadn't yet been assigned. 这也意味着,当撤回数据时,对于尚未分配的体素,我可以默认为Voxel.Empty。

In your case you might not need a default value but using a dictionary might prove more helpful than an array. 在您的情况下,您可能不需要默认值,但使用字典可能比数组更有用。

The up shot ... Arrays are a tad faster for some things but when you consider all of your usage scenarios for the data you may find that overall the gains of using a dictionary are worth a slight allocation cost. 很快……数组在某些方面更快一些,但是当您考虑数据的所有使用场景时,您可能会发现使用字典的总体收益值得付出一点分配成本。

In testing I found that if I was prepared to drop from something like 100ms per thousand to say 120ms per thousand on allocations I could then retrieve the data 100% faster for most of the queries I was performing on the set. 在测试中,我发现,如果我准备从分配的每百毫秒100ms下降到说的每千毫秒120ms,那么对于在集合上执行的大多数查询,我可以将数据检索速度提高100%。

Reason for my suggestion here: 我在这里提出建议的原因:

It looks like you don't know the size of your data set and using an array only makes sense if you do know the size otherwise you tie up needless "pre allocated chunks of ram" for no reason in order to make your code ready for any eventuality you want to throw at it. 似乎您不知道数据集的大小,并且仅在知道大小的情况下使用数组才有意义,否则您会无故捆绑不必要的“预先分配的ram块”以使代码准备就绪您想丢掉的任何偶然事件。

Hope this helps. 希望这可以帮助。

You may try List<T> and ToArray() method associate with List. 您可以尝试将List<T>ToArray()方法与List关联。 And it's supported by XNA framework too ( MSDN ). 而且XNA框架( MSDN )也支持它。

List is a successor to ArrayList and provide more features and strongly typed (A good comparison ). ListArrayList的后继者,并提供更多功能和strongly typed (很好的比较 )。

About performance, List<T>.ToArray is a O(n) operation . 关于性能, List<T>.ToArrayO(n) operation And I suggest you to break your lengthy array to sort of portions which you can name with a key [Some sort of unique identifier to a region or so on] . 我建议您将冗长的数组分解为可以用key [某些区域的唯一标识符等]命名的部分。 And store relevant information in a List and use Dictionary like Dictionary<Key, List<T>> which could reduce operations involved. 并将相关信息存储在List并使用Dictionary例如Dictionary<Key, List<T>>可以减少涉及的操作。 Also you can process required models with priority based approach which would give a performance gain over processing complete array at once. 您还可以使用基于优先级的方法来处理所需的模型,这将比一次性处理完整的array带来更高的性能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM