Witch方法更好,或者更好的方法是什么:
Stuffs[] stuffs = getStuffs();
1)
foreach (var stuff in stuffs.Where(x => x.StartDate <= DateTime.Now.AddDays(-1) && x.EndDate != DateTime.MinValue))
{
}
2)
foreach (var stuff in stuffs.Where(x => x.StartDate <= DateTime.Now.AddDays(-1) && x.EndDate != DateTime.MinValue).ToList())
{
}
3)
stuffs = stuffs.Where(x => x.StartDate <= DateTime.Now.AddDays(-1) && x.EndDate != DateTime.MinValue).ToArray();
foreach (var stuff in stuffs)
{
}
我认为3号的性能更好。还有更多想法吗?
答案 0 :(得分:2)
您应该检查,但通常获取数据以及您在循环中执行的操作需要多次迭代。第一个应该更快,因为你没有创建一个新的列表,这里你不需要
我还建议将DateTime.Now.AddDays(-1)
放在变量中 - 除了possible speed benefits之外,其值可能会在迭代期间发生变化,这可能会影响程序的正确性。
答案 1 :(得分:2)
通常:衡量!
为了便于阅读,我会说1和3的混合。在foreach
的标题中直接有一行代码变得有点不可读,所以我将查询放在一个单独的行中在循环之上:
var stuffs = from x in getStuffs()
where x.StartDate <= DateTime.Now.AddDays(-1) &&
x.EndDate != DateTime.MinValue
select x;
或
var stuffs = getStuffs().Where(x => x.StartDate <= DateTime.Now.AddDays(-1) && x.EndDate != DateTime.MinValue);
但是你希望。但在那之后,使用普通的foreach
循环:
foreach (var s in stuffs) {
}
此外,无需转换为列表,因为foreach
可以迭代任何可迭代的集合,包括LINQ的惰性评估的东西。转换到列表可能实际上是成本你的时间。但是,如果您需要在循环开始之前对进行评估,那么您可能需要这样做,但这并不是一个常见的需求(根据我的经验)。
答案 2 :(得分:0)
第一个通常最适合表现。它会在您循环访问数据时对其进行过滤,因此它不会为列表或数组分配空间来保存所有项目。
第二个和第三个表现几乎相同。它们都过滤数据并将结果放入数组中,并在需要时通过复制到新数组来增长数组。
第三种方法还用过滤数据数组替换原始数据,如果稍后使用数据,这将是相关的。此外,这样做可以释放原始数据,以便在需要时可以对其进行垃圾收集,这对于源数组非常大的特殊情况下的性能可能更好,并且如果在代码中使用大量内存在循环中。
如果比较选项之间的速度,您将看不到太大差异。分配数组并不需要花费太多时间,但稍后会产生很小的影响,因为它们最终必须进行垃圾回收。