2

5000 以上のアイテムを含む一般的なコレクションがあります。すべてのアイテムは一意であるため、SingleOrDefault を使用してコレクションからアイテムを取得しました。今日、Red Gate ANTS プロファイラーを使用してコードを調べたところ、SingleOrDefault 呼び出しが (~3.5 秒) で 5000 回の反復で 1800 万回ヒットしたのに対し、FirstOrDefault に変更すると (~1.5 秒) で 900 万回ヒットしたことがわかりました。

コレクション内のすべてのアイテムが一意であることがわかっているため、SingleOrDefault を使用しました。

編集:これは SingleOrDefault を使用することになっている正確なシナリオであるにもかかわらず、FirstOrDefault が SingleOrDefault よりも高速である理由は疑問です。

4

5 に答える 5

9

SingleOrDefault()複数ある場合は例外が発生します。それを判断するには、1 つしかないことを確認する必要があります。

一方、FirstOrDefault()見つけたら探すのをやめることができます。したがって、多くの場合、かなり高速になると思います。

于 2013-05-20T19:06:06.807 に答える
4

SingleOrDefault(predicate)は、指定された述語に一致するアイテムが最大 1 つであることを確認するため、コレクションの先頭付近で一致するアイテムが見つかった場合でも、IEnumerable.

FirstOrDefault(predicate)コレクション内で一致するアイテムが見つかるとすぐに停止します。「最初の一致」IEnumerableIEnumerable.

一連のNアイテムの場合、SingleOrDefaultは述語を実行し、述語を (平均して)N回実行します。これは、の「ヒット数」が の 2 倍である理由を説明しています。FirstOrDefaultN/2SingleOrDefaultFirstOrDefault

コレクションのソースがユーザーとシステムによって制御されているため、一致するアイテムが 1 つしかないことがわかっている場合は、 FirstOrDefault. たとえば、コレクションがユーザーからのものである場合SingleOrDefault、ユーザーの入力のチェックとして使用することは理にかなっています。

于 2013-05-20T19:05:21.753 に答える
1

FirstOrDefault は最初のヒットで返されます。SinglerOrDefault は最初のヒットでは返されませんが、他のすべての要素も調べて、一意かどうかを確認します。そのため、ほとんどの場合、FirstOrDefault の方が高速です。一意性チェックが必要ない場合は、FirstOrDefault を使用します。

于 2013-05-20T19:10:51.817 に答える
1

SingleOrDefaultまたは のどちらかを選択することがボトルネックになるとはとても思えませんFirstOrDefault。プロファイリング ツールが、フライするより大きな魚を強調することを願っています。あなた自身のメトリクスは、これが特定の反復のほとんど識別できない時間単位になることを明らかにしています。

しかし、私はあなたの期待に一致するものを使用することをお勧めします. つまり、述語に一致するものが複数あるとエラーになりますか? そうである場合は、その期待を強制する方法を使用してください。SingleOrDefault. (同様に、何もないこともエラーである場合は、単純に を使用してSingleください。)複数のエラーでない場合はFirst、代わりにバリアントを自由に使用してください。

他の回答が議論しているように、なぜ一方が他方よりもわずかに高速になるのかが明らかになるはずです。1 つは制約を強制することです。これはもちろん、ロジックを実行することによって実現されます。もう一方はその特定の制約を強制していないため、それによって遅れることはありません。

于 2013-05-20T20:19:19.657 に答える