是处理每个列表元素更好,还是先找到要处理的元素
本文关键字:处理 元素 列表元素 更好 | 更新日期: 2023-09-27 18:35:10
我有一个列表:List<MyClass> MyList = new List<MyClass>();
.
MyClass
有方法SetBool
和IsTrue
。我必须将此列表的每个对象都设置为 false ( obj.SetBool(false)
)。
有两种可能的方法:
第一:
foreach (MyClass obj in MyList)
{
obj.SetBool(false)
}
第二:
List<MyClass> MyList2 = MyList.Where(c => c.IsTrue()).ToList();
foreach (MyClass obj in MyList2)
{
obj.SetBool(false)
}
如果我使用第一个,它可能会很慢,因为它会更改每个元素。第二种方法也可能很慢,因为它必须首先找到对象。
所以我的问题是:哪一个会更快(我可能在列表中有大量元素)为什么?
最快的是组合:
foreach (MyClass obj in MyList)
{
if (obj.IsTrue())
obj.SetBool(false)
}
但是,只有当SetBool()
进行一些广泛的验证或计算时,与第一个版本的差异才有意义,并且比Istrue()
昂贵得多。
可能是使用for
for(int i=0;i<MyList.Count;i++)
{
if (MyList[i].Istrue())
MyList[i].SetBool(false)
}
所有这些优化都是上下文相关的。
很多缺点是:
- 您的列表大小
- 该列表中的真值分布
- SetBool方法是否做了一些"沉重"的事情
第一个会更短。第二个将很长。
Why ?
假设您列表中有 100 个项目。
对于第一个代码段,它只会迭代 100 多个项目。
而对于第二个片段,它将循环超过 100 然后取出 15(让我们假设)。然后它将迭代这 15 个。
所以基本上它迭代了 115 个项目,以获得 100 个项目的列表。
相反,您可以通过这种方式进行检查
foreach (MyClass obj in MyList)
{
if (obj.IsTrue())
obj.SetBool(false)
}
这将遍历所有这些,但仅在真实的情况下调用SetBool()
这取决于,如果SetBool
是一个昂贵的函数,那么它确实很重要。再说一次,如果isTrue
是一个昂贵的功能,那么它确实很重要。
但无论如何,与其使用您的第二种方式,我宁愿使用
foreach (MyClass obj in MyList.Where(c => c.IsTrue()))
{
obj.SetBool(false)
}
与实现相比,这将降低速度和内存消耗。但同样,你必须衡量它。如果检查需要更长的时间,如果项目是真的,那么设置对象,那么就使用你的第一种方法。如果是相反的方式,那么使用我的方法。
就大 O 表示法而言,两者都以 O(n) 运行
对于SetBool
的每一个合理实现,第一个版本应该更快。