在 LINQ 查询中调用 ToList() 或 ToArray() 更好吗? [英] Is it better to call ToList() or ToArray() in LINQ queries?

查看:37
本文介绍了在 LINQ 查询中调用 ToList() 或 ToArray() 更好吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我经常遇到这样的情况,我想在我声明的地方评估查询.这通常是因为我需要对其进行多次迭代并且计算起来很昂贵.例如:

I often run into the case where I want to eval a query right where I declare it. This is usually because I need to iterate over it multiple times and it is expensive to compute. For example:

string raw = "...";
var lines = (from l in raw.Split('
')
             let ll = l.Trim()
             where !string.IsNullOrEmpty(ll)
             select ll).ToList();

这很好用.但是如果我不打算修改结果,那么我不妨调用 ToArray() 而不是 ToList().

This works fine. But if I am not going to modify the result, then I might as well call ToArray() instead of ToList().

我想知道 ToArray() 是否是通过首先调用 ToList() 来实现的,因此内存效率低于仅调用 ToList()>.

I wonder however whether ToArray() is implemented by first calling ToList() and is therefore less memory efficient than just calling ToList().

我疯了吗?我应该只调用 ToArray() - 知道内存不会被分配两次是安全可靠的吗?

Am I crazy? Should I just call ToArray() - safe and secure in the knowledge that the memory won't be allocated twice?

推荐答案

除非您只是需要一个数组来满足其他约束,否则您应该使用 ToList.在大多数情况下,ToArray 将比 ToList 分配更多的内存.

Unless you simply need an array to meet other constraints you should use ToList. In the majority of scenarios ToArray will allocate more memory than ToList.

两者都使用数组来存储,但是ToList 有一个更灵活的约束.它需要数组至少与集合中的元素数量一样大.如果数组更大,那不是问题.但是 ToArray 需要将数组的大小精确到元素的数量.

Both use arrays for storage, but ToList has a more flexible constraint. It needs the array to be at least as large as the number of elements in the collection. If the array is larger, that is not a problem. However ToArray needs the array to be sized exactly to the number of elements.

为了满足这一限制,ToArray 通常比 ToList 多做一次分配.一旦它有一个足够大的数组,它就会分配一个完全正确大小的数组,并将元素复制回该数组.它可以避免这种情况的唯一时间是当数组的增长算法恰好与需要存储的元素数量(肯定是少数)一致时.

To meet this constraint ToArray often does one more allocation than ToList. Once it has an array that is big enough it allocates an array which is exactly the correct size and copies the elements back into that array. The only time it can avoid this is when the grow algorithm for the array just happens to coincide with the number of elements needing to be stored (definitely in the minority).

编辑

有几个人问我在 List 值中有多余的未使用内存的后果.

A couple of people have asked me about the consequence of having the extra unused memory in the List<T> value.

这是一个合理的担忧.如果创建的集合是长期存在的,在创建后永远不会被修改并且很有可能进入 Gen2 堆,那么你最好预先分配 ToArray 的额外分配.

This is a valid concern. If the created collection is long lived, is never modified after being created and has a high chance of landing in the Gen2 heap then you may be better off taking the extra allocation of ToArray up front.

总的来说,虽然我发现这种情况比较少见.更常见的是看到许多 ToArray 调用会立即传递给其他短暂的内存使用,在这种情况下 ToList 显然更好.

In general though I find this to be the rarer case. It's much more common to see a lot of ToArray calls which are immediately passed to other short lived uses of memory in which case ToList is demonstrably better.

这里的关键是配置文件,配置文件,然后再配置文件.

The key here is to profile, profile and then profile some more.

这篇关于在 LINQ 查询中调用 ToList() 或 ToArray() 更好吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆