636 votes

Quelle méthode est la plus performante : .Any() ou .Count() > 0 ?

Dans le System.Linq nous pouvons maintenant étendre notre de IEnumerable pour avoir le Tout() y Compter() méthodes d'extension .

On m'a dit récemment que si je veux vérifier qu'une collection contient 1 ou plusieurs éléments, je dois utiliser la fonction .Any() au lieu de la méthode d'extension .Count() > 0 car la méthode d'extension .Count() La méthode d'extension doit itérer à travers tous les éléments.

Deuxièmement, certaines collections ont un propriété (pas une méthode d'extension) qui est Count ou Length . Serait-il préférable de les utiliser, au lieu de .Any() ou .Count() ?

yea / nae ?

0 votes

Il est préférable d'utiliser Any() sur les Enumérables et Count sur les Collections. Si quelqu'un pense qu'écrire '(somecollection.Count > 0)' sera source de confusion ou de problèmes de lisibilité, il vaut mieux l'écrire comme une méthode d'extension et la nommer Any(). Tout le monde sera alors satisfait. Du point de vue des performances et de la lisibilité. Ainsi, tout votre code sera cohérent et chaque développeur de votre projet ne devra pas s'inquiéter de choisir entre Count et Any.

2 votes

Vous avez vu Count() > 0 vs Any(), mais avez-vous vu Distinct().Count() > 1 vs Distinct().Skip(1).Any() ? Cette dernière est définitivement beaucoup plus rapide pour un grand nombre d'éléments où Count doit itérer sur l'ensemble pour obtenir un compte. Skip(1).Any() évite l'énumération complète. 100k itérations de la vérification d'un tableau de 1000 éléments avec des chaînes de 1 caractère qui s'exécute en environ 4000ms pour Count() > 1, s'exécute en seulement 20ms pour Skip(1).Any().

7voto

Lasse V. Karlsen Points 148037

Eh bien, le .Count() n'utilisera pas la méthode d'extension .Count mais je suppose que vous n'utiliserez pas la propriété .Count() pour une simple collection, mais plutôt à la fin d'une instruction LINQ avec des critères de filtrage, etc.

Dans ce contexte, .Any() sera plus rapide que .Count() > 0 .

6voto

Cela dépend de la taille de l'ensemble de données et de vos exigences en matière de performances.

Si ce n'est rien de gigantesque, utilisez la forme la plus lisible, ce qui, pour moi, est n'importe laquelle, car elle est plus courte et plus lisible qu'une équation.

3voto

Bronks Points 67

Vous pouvez faire un test simple pour le savoir :

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;

Vérifiez les valeurs de testCount et testAny.

1 votes

Voici un test avec votre code pour la propriété Count contre Any() La propriété Count gagne contre Any() avec +2x -. lien

1 votes

Pour un meilleur résultat, vous pourriez faire ces comparaisons 1000 fois (ou plus). Cela permet d'obtenir une moyenne des résultats et d'éviter les pics aléatoires.

0 votes

Lorsque vous effectuez des tests comme la méthode mentionnée ci-dessus, vous devez prendre en compte de nombreux autres facteurs, tels que la charge sur votre base de données/réseau, la mise en cache du plan du côté de la base de données, etc. Pour effectuer un test précis, vous devez donc concevoir un environnement isolé et précis.

2voto

Thiago Coelho Points 61

A propos de la Compter() si la méthode IEnumarable es un ICollection alors nous ne pouvons pas itérer sur tous les éléments parce que nous pouvons récupérer l'élément Comte domaine de ICollection si le IEnumerable n'est pas un ICollection nous devons itérer à travers tous les éléments en utilisant un tandis que avec un MoveNext Jetez un coup d'œil au code du .NET Framework :

public static int Count<TSource>(this IEnumerable<TSource> source)
{
    if (source == null) 
        throw Error.ArgumentNull("source");

    ICollection<TSource> collectionoft = source as ICollection<TSource>;
    if (collectionoft != null) 
        return collectionoft.Count;

    ICollection collection = source as ICollection;
    if (collection != null) 
        return collection.Count;

    int count = 0;
    using (IEnumerator<TSource> e = source.GetEnumerator())
    {
        checked
        {
            while (e.MoveNext()) count++;
        }
    }
    return count;
}

Référence : Source de référence énumérable

1voto

Janmejay Kumar Points 118

Si vous utilisez l'Entity Framework et que vous avez une énorme table avec de nombreux enregistrements Tout() sera beaucoup plus rapide. Je me souviens d'une fois où je voulais vérifier si une table était vide alors qu'elle contenait des millions de lignes. Il fallait 20 à 30 secondes pour que Count() > 0 soit terminé. C'était instantané avec Tout() .

Tout() peut améliorer les performances car il n'est pas nécessaire d'itérer la collection pour obtenir le nombre de choses. Il lui suffit d'atteindre l'un d'entre eux. Ou, pour, disons, LINQ-to-Entities, le SQL généré sera IF EXISTS(...) plutôt que SELECT COUNT ... ou même SELECT * .....

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X