662

System.Linq名前空間では、IEnumerable を拡張しAny()およびCount() 拡張メソッドを持つことができるようになりました。

コレクションに 1 つ以上の項目が含まれていることを確認したい場合、.Any()拡張メソッドではなく拡張メソッドを使用する必要があると最近言われまし.Count() > 0た。.Count()拡張メソッドはすべての項目を反復処理する必要があるからです。

次に、一部のコレクションには、 または であるプロパティ(拡張メソッドではない) がありCountますLength。またはの代わりにそれらを使用する方が良いでしょう.Any().Count()?

はい/なえ?

4

11 に答える 11

804

.Lengthorを含むもの.Count( ICollection<T>IList<T>、など) から開始する場合、空でないシーケンスをチェックするために必要な // シーケンスをList<T>通過する必要がないため、これが最速のオプションになります。 .GetEnumerator()MoveNext()Dispose()Any()IEnumerable<T>

justIEnumerable<T>の場合、1 回の反復のみを確認するだけでよいため、通常Any()は高速になります。ただし、LINQ-to-Objects の実装は(最適化として使用して)チェックすることに注意してください。そのため、基になるデータ ソースが直接リスト/コレクションである場合、大きな違いはありません。非ジェネリックを使用しない理由を聞かないでください...Count()ICollection<T>.CountICollection

もちろん、LINQ を使用してフィルタリングした場合 ( Whereetc)、イテレータ ブロック ベースのシーケンスになるため、このICollection<T>最適化は役に立ちません。

一般的にIEnumerable<T>: 固執するAny();-p

于 2008-11-20T12:37:04.550 に答える
13

編集: EF バージョン 6.1.1 で修正されました。そして、この答えはもはや現実的ではありません

SQL Server と EF4-6 の場合、Count() は Any() よりも約 2 倍速く実行されます。

Table.Any() を実行すると、次のようなものが生成されます (アラート: 理解しようとしている脳を傷つけないでください)

SELECT 
CASE WHEN ( EXISTS (SELECT 
    1 AS [C1]
    FROM [Table] AS [Extent1]
)) THEN cast(1 as bit) WHEN ( NOT EXISTS (SELECT 
    1 AS [C1]
    FROM [Table] AS [Extent2]
)) THEN cast(0 as bit) END AS [C1]
FROM  ( SELECT 1 AS X ) AS [SingleRowTable1]

これには、条件付きの行を 2 回スキャンする必要があります。

Count() > 0自分の意図を隠してしまうので、書くのは好きではありません。これにはカスタム述語を使用することを好みます。

public static class QueryExtensions
{
    public static bool Exists<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate)
    {
        return source.Count(predicate) > 0;
    }
}
于 2014-01-03T16:32:26.523 に答える
7

それは、データ セットの大きさとパフォーマンス要件によって異なります。

それが巨大ではない場合は、最も読みやすい形式を使用します。これは、方程式よりも短くて読みやすいためです。

于 2014-12-22T23:43:13.713 に答える
3

これを理解するための簡単なテストを行うことができます:

var query = //make any query here
var timeCount = new Stopwatch();
timeCount.Start();
if (query.Count > 0)
{
}
timeCount.Stop();
var testCount = timeCount.Elapsed;

var timeAny = new Stopwatch();
timeAny.Start();
if (query.Any())
{
}
timeAny.Stop();
var testAny = timeAny.Elapsed;

testCount と testAny の値を確認します。

于 2017-01-20T17:15:51.127 に答える