1

リストがあります: List<MyClass> MyList = new List<MyClass>();.

MyClassメソッドSetBoolとがありIsTrueます。このリストのすべてのオブジェクトを false ( obj.SetBool(false)) に設定する必要があります。

次の 2 つの方法があります。

初め:

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

2番:

List<MyClass> MyList2 = MyList.Where(c => c.IsTrue()).ToList();

foreach (MyClass obj in MyList2)
{
    obj.SetBool(false)
}

最初のものを使用すると、すべての要素が変更されるため、遅くなる可能性があります。2 番目の方法も、最初にオブジェクトを見つける必要があるため、遅くなる可能性があります。

だから私の質問は次のとおりです。どちらが高速になりますか(リストに非常に多くの要素がある可能性があります)、なぜですか?

4

5 に答える 5

4

最速の組み合わせは次のとおりです。

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

しかし、最初のバージョンとの違いは、大規模な検証や計算を行った場合にのみ意味がSetBool()あり、 よりもはるかに高価ですIstrue()

于 2012-05-23T12:58:28.913 に答える
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 に答える
2

まず短くなります。2つ目は長くなります。

Why ?

リストに 100 個のアイテムがあるとします。

最初のスニペットでは、100 項目のみを反復します。

一方、2 番目のスニペットでは、100 をループしてから 15 を取り出します (仮定しましょう)。次に、それらの 15 を反復処理します。

したがって、基本的には、100 個の項目のリストに対して 115 回以上反復しました。

代わりに、この方法で確認できます

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

これはそれらすべてを反復しますが、SetBool()true の場合にのみ呼び出します

于 2012-05-23T12:57:29.073 に答える
1

場合によって異なりますSetBoolが、高価な関数である場合は重要です。繰り返しになりisTrueますが、 が高価な関数である場合、これも重要です。

とにかく、あなたの2番目の方法を使用する代わりに、私はむしろ使用します

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

これにより、実装と比較して速度とメモリ消費が減少します。繰り返しになりますが、測定する必要があります。チェックに時間がかかる場合、アイテムが IsTrue の場合、オブジェクトを設定する場合は、最初の方法を使用してください。逆の場合は、私の方法を使用してください。

Big O表記に関しては、どちらもO(n)で実行されます

于 2012-05-23T13:03:17.007 に答える
0

SetBool最初のバージョンのすべての合理的な実装については、より高速にする必要があります。

于 2012-05-23T12:57:05.457 に答える