1

我有一个清单:List<MyClass> MyList = new List<MyClass>();

MyClass有方法SetBoolIsTrue. 我必须将此列表中的每个对象都设置为 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)
}

如果我使用第一个它可能会很慢,因为它会改变每个元素。第二种方式也可能很慢,因为它必须先找到对象。

所以我的问题是:哪一个会更快(我的列表中可能有非常多的元素),为什么?

4

5 回答 5

4

最快的是组合:

foreach (MyClass obj in MyList)
{
    if (obj.IsTrue())
        obj.SetBool(false)
}

但是与您的第一个版本的差异只有在进行SetBool()一些广泛的验证或计算时才有意义,并且比Istrue().

于 2012-05-23T12:58:28.913 回答
2

首先会更短。第二个会很长。

Why ?

假设您在列表中有 100 个项目。

对于第一个片段,它将仅迭代 100 多个项目。

而对于第二个片段,它将循环超过 100,然后取出 15(让我们假设)。然后它将遍历这 15 个。

所以基本上它迭代了超过 115 次以获得 100 个项目的列表。

相反,您可以通过这种方式进行检查

foreach (MyClass obj in MyList)
{
    if (obj.IsTrue())
        obj.SetBool(false)
}

这将遍历所有这些,但SetBool()只会在正确的地方调用

于 2012-05-23T12:57:29.073 回答
2

更快的一个可能是(但就像在您的特定情况下必须测量所有内容一样)是使用for

for(int i=0;i<MyList.Count;i++)
{
    if (MyList[i].Istrue())
        MyList[i].SetBool(false)
}

所有这些优化都是上下文相关的。

很多取决于:

  • 你的列表大小
  • 该列表中的真实值分布
  • SetBool 方法是否做一些“重”的事情
于 2012-05-23T13:00:05.167 回答
1

这取决于,如果SetBool是一个昂贵的功能,那么它确实很重要。再说一次,如果这isTrue是一个昂贵的功能,那么它确实很重要。

但无论如何,我宁愿使用你的第二种方式,而不是使用你的第二种方式

foreach (MyClass obj in MyList.Where(c => c.IsTrue()))
{
    obj.SetBool(false)
}

与您的实现相比,这将降低速度和内存消耗。但同样,你必须测量它。如果检查需要更长的时间,如果项目 IsTrue 然后设置对象,那么只需使用您的第一种方式。如果是反之,那就用我的方法。

大 O 表示法而言,两者都以 O(n) 运行

于 2012-05-23T13:03:17.007 回答
0

对于SetBool第一个版本的每个合理实现应该更快。

于 2012-05-23T12:57:05.457 回答