哪个更有效:List.Add() 或 System.Array.Resize()?
我试图确定 List
与使用 Array.Resize()
方法相比何时更有效。
Array.Resize 的文档说它会复制整个数组,并将其放入一个新对象中。旧的对象将不得不被丢弃。这个旧对象位于哪里?在栈上还是在堆上?
我不知道 List.Add() 是如何工作的。
有谁知道 List.Add 方法与静态 Array.Resize 方法相比如何?
我对内存使用(和清理)感兴趣,以及 300 个值类型与 20,000 个值类型相比哪个更好。
不管怎样,我计划在 .NET 的嵌入式版本之一上运行此代码。可能是 .NET Gadgeteer
I'm trying to determine when it's more efficient to List<T>.Add()
versus using the Array.Resize()
method.
The documentation for Array.Resize says it makes a copy of the entire array, and places it into a new object. The old object would have to be discarded. Where does this old object reside? On the stack or the heap?
I don't know how List.Add() works.
Does anyone know how the List.Add method compares to the static Array.Resize method?
I'm interested in memory usage (and cleanup), and what is better for 300 value types, versus 20,000 value types.
For what it's worth, I'm planning on running this code on one of the embedded flavors of .NET. Potentially the .NET Gadgeteer
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您应该使用
List
。使用
Array.Resize
将迫使您在每次添加项目时单独扩展数组,从而使您的代码慢得多。 (因为数组不能有备用容量)List
由数组支持,但保留用于放入项目的备用容量。添加项目所需要做的就是在数组中设置一个元素并增加其内部
size
计数器。当数组已满时,列表的容量将增加一倍,从而可以轻松地再次添加未来的项目。
You should use a
List<T>
.Using
Array.Resize
will force you to expand the array separately each time you add an item, making your code much slower. (since arrays cannot have spare capacity)A
List<T>
is backed by an array, but holds spare capacity to put items into.All it needs to do to add an item is to set an element in the array and increase its internal
size
counter.When the array gets full, the list will double its capacity, allowing future items to be added effortlessly again.
.NET Micro Framework 不支持泛型,因此我将使用数组,根据需要复制并销毁它。
我可能会将该性能与此处 powertools 库中提到的展开链接列表进行比较:
C# 中有展开链接列表的实现吗?
The .NET Micro Framework does not support generics, so I will be using an array, copying and destroying it as needed.
I might compare that perfmance to the unrolled linked list mentioned in the powertools library here:
Any implementation of an Unrolled Linked List in C#?
.NET Micro Framework(尚)不支持泛型。您在动态集合方面受到限制。
选择方法时需要考虑的一件事是微控制器上的托管代码非常非常慢。托管 .NET Micro Framework 对象中的许多操作实际上只是调用本机代码来完成工作。这要快得多。
例如,比较在 for 循环中逐元素复制数组与调用 Array.Copy() ,后者本质上执行相同的操作,但在本机代码中。
如果可能,请使用这些本机扩展以获得更好的性能。另请考虑查看 CodePlex 上的 MicroLinq 项目。有一个子项目专门用于增强 NETMF 上的集合(也可以作为 NuGet 包 提供)。该代码可免费获取并公开许可用于任何目的。 (全面披露:我是该项目的开发人员。)
如果您可以分配一个大数组并跟踪保存真实数据的最大位置,这将是最快的,但需要更多的工作/思考投入到设计中,并占用了构建很酷的东西的时间。
The .NET Micro Framework does not (yet) support generics. You're limited with regard to dynamic collections.
One thing to consider when picking your approach is that managed code on the microcontroller is very, very slow. Many operations in the managed .NET Micro Framework objects are actually just calling into native code to do the work. This is much faster.
For instance, compare copying an array element by element in a for loop versus calling Array.Copy() which essentially does the same thing but in native code.
Where possible, use these native extensions to get better performance. Also consider taking a look at the MicroLinq project on CodePlex. There is a sub project devoted just to enhanced collections on NETMF (also available as a NuGet package). The code is freely available and openly licensed for any purpose. (Full disclosure: I'm the dev of that project.)
If you can get away with allocating a large array and keeping track of the max position at which real data has been saved, this would be the fastest but requires more work / thought put into the design and takes away time from building the cool stuff.
只有经常调整数组大小(例如每次添加项目时),列表才会更快。但是,如果每隔几帧调整一次大小,列表和内置数组应该是等效的,也许数组更快。
List will only be faster if you resize the array frequently, for example every time you add an item. However if you resize it every few frames, List and built-in arrays should be equivalent, perhaps arrays still faster.
我在反编译后看到了 List 实现,发现它使用 Array.Resize() 作为内部数组。但它管理元素计数器并使用数组的长度作为容量,并在调用 Add() 时使用一些额外空间调整数组的大小。因此,我想您可以针对您的情况制定比 List 更优化的分配策略。但您必须手动管理元素计数器。此外,您还可以在访问数组元素时消除索引器开销,因为 List 内的索引器只是请求内部数组元素的方法。我认为如果仅是瓶颈,则值得用手动调整大小的数组替换列表。
I've seen List implementation after decompilation and found that it uses Array.Resize() for internal array. But it manages elements counter and uses array's length as capacity and resizes the array with some extra space when you call Add(). So, I guess you can develop more optimal allocation strategy than List for your case. But you will have to manage elements counter manually. Also you'll get rid of indexers overhead when accessing array elements, because indexers inside List are just methods that request internal array elements. I think it is worth to replace List by array with manual resize if it is bottleneck only.