Kla*_*Nji 4 linq deferred-execution
基于以下代码:
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
}
}
Run Code Online (Sandbox Code Playgroud)
在过滤List的过程中,我的理解是调用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
}
}
Run Code Online (Sandbox Code Playgroud)
TIA.
如果基础数据源是IList<T>
,Enumerable.Count()
将.Count
作为优化调用该属性,因此没有*性能损失.如果不是,则强制进行枚举.仔细考虑这一点.
var someList = new List<int>();
var count = someList.Count(); // will use .Count property
var count = someList.OrderBy(x => x).Count(); // will force enumeration
Run Code Online (Sandbox Code Playgroud)
在这个例子中,我只是在第二个语句中得到列表的计数.在第三个,我正在订购列表,然后得到计数.对列表进行排序会返回序列,而不是列表.因此,该Count()
方法不是一个IList<T>
,而是一个IEnumerable<T>
.在这种情况下,必须枚举查询以获取结果,并且将产生与其一起出现的任何成本(在这种情况下,排序).
鉴于此,在您的第一个代码段中,您将枚举您的查询两次.一旦得到计数,一旦在foreach.这将执行两次分组数据的所有逻辑.您的第二个示例将仅执行一次分组操作,同时显然迭代foreach中的结果列表,这应该比第二次执行分组操作更便宜.(您是否可以衡量节省量将完全取决于原始列表中数据的大小和/或来源.如有疑问,请对其进行分析.)
*对于间接层,可能会有一个小的测量惩罚,如果您认为它是一个真正的瓶颈,您将不得不对此进行分析.但是把这个Count()
方法想象成
if (sequence is IList<T>)
{
return ((IList<T>)sequence).Count
}
else
{
/* perform enumeration */;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1968 次 |
最近记录: |