LINQ:使用 IEnumerable.Count() 或 IList.Count 以获得更好的性能
基于以下代码:
var grouped = filters.GroupBy(p => p.PropertyName);
int numOfRowElements = grouped.Count();
foreach (IGrouping<string, PropertyFilter> filter in grouped)
{
foreach (var propertyFilter in filter)
{
// do something
}
}
wherefiltersaList,我的理解是调用 IEnumerable.Count() 强制执行查询。这次执行的结果是否存储在分组变量中,然后在 foreach 循环中使用,或者 foreach 循环是否强制再次执行查询?这样做会更好吗?
var grouped = filters.GroupBy(p => p.PropertyName).ToList();
int numOfRowElements = grouped.Count;
foreach (IGrouping<string, PropertyFilter> filter in grouped)
{
foreach (var propertyFilter in filter)
{
// do something
}
}
TIA。
Based on the following code:
var grouped = filters.GroupBy(p => p.PropertyName);
int numOfRowElements = grouped.Count();
foreach (IGrouping<string, PropertyFilter> filter in grouped)
{
foreach (var propertyFilter in filter)
{
// do something
}
}
where filters a List, my understanding is that calling IEnumerable.Count() forces the query to be executed. Is the result of this execution stored in the grouped variable, which is then used in the foreach loop, or does the foreach loop force the query to be executed again? Would it be better to do this instead?
var grouped = filters.GroupBy(p => p.PropertyName).ToList();
int numOfRowElements = grouped.Count;
foreach (IGrouping<string, PropertyFilter> filter in grouped)
{
foreach (var propertyFilter in filter)
{
// do something
}
}
TIA.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
更多
发布评论
评论(1)
如果基础数据源是
IList
,Enumerable.Count()
将调用.Count
属性:优化,因此没有*性能损失。如果不是,将强制进行枚举。请仔细考虑这一点。在此示例中,我只是获取第二个语句中列表的计数。在第三个中,我对列表进行排序,然后进行计数。对列表进行排序会返回一个序列,而不是列表。因此,
Count()
方法不适用于IList
,而是IEnumerable
>。在这种情况下,必须枚举查询才能获取结果,并将产生随之而来的任何成本(在本例中为排序)。鉴于此,在第一个代码片段中,您将枚举查询两次。一次获取计数,一次在 foreach 中。这将执行将数据分组两次的所有逻辑。您的第二个示例将仅执行一次分组操作,同时显然会迭代 foreach 中的结果列表,这应该比第二次执行分组操作更便宜。 (您是否可以衡量节省量将完全取决于原始列表中数据的大小和/或来源。如有疑问,请对其进行分析。)
*可能会存在小测量惩罚间接层,如果您认为这是真正的瓶颈,则必须对其进行分析。但将
Count()
方法视为If the underlying datasource is
IList<T>
,Enumerable.Count()
will invoke the.Count
property as an optimization, so there is no* performance penalty. If it is not, an enumeration will be forced. Consider this carefully.In this example, I'm just getting the count of the list in the second statement. In the third, I'm ordering the list and then getting the count. Ordering the list returns a sequence, not a list. Therefore, the
Count()
method is not working on anIList<T>
, but anIEnumerable<T>
. In this case, the query must be enumerated to acquire the result and will incur whatever cost that comes along with it (in this case, the ordering).In light of this, in your first snippet, you will enumerate your query twice. Once to get the count, once in the foreach. This will perform all the logic to group your data twice. Your second example will perform the grouping operations just once, while obviously iterating over the resulting list in the foreach, which should be less expensive than also performing the grouping operation a second time. (Whether you can measure a savings will entirely depend upon the size and/or source of the data in the original list. When in doubt, profile it.)
*There may be a small measured penalty for the layer of indirection, you'll have to profile this if you believe it is a true bottleneck. But think of the
Count()
method as