i Itérale à l'aide d'un iéenérable à la suite d'une requête LINQ en utilisant (élémat, compte) et (foreach). À ma surprise, la différence de performance est de 25-30 fois! Pourquoi est-ce?
7 Réponses :
parce que Pourquoi ne pas faire p> ollementat code> est itération via le ienumerable code> chaque fois que vous l'appelez. iEnumerable code> s ne sont pas indexés, donc ellementat code> doit être implémenté à l'aide de getenumerator () code>. total = result.Sum();
... Comme compte () code>. Il n'y a pas besoin d'expression de Lambda, BTW. Juste résultat.sum () code> devrait être bien.
@Jon Skeet, soupçonné donc mais devait aller vérifier en premier. Semble évident maintenant, ALA SELECT () CODE>
Total + = P; Code> est à titre de démonstration. La logique réelle est différente.
Parce que chaque appel iTère sur la liste. La solution simple consiste à appeler .tolist () avant itération, une meilleure solution consiste à arrêter itérant. meilleure solution: p> total = result.Sum();
La différence de performance est due au fait que le ienumerable code> ne vous permet pas d'obtenir par index, donc chaque fois que vous appelez élémentaire code> dans votre première boucle, il faut Itérate à chaque article jusqu'à ce qu'il atteigne l'élément que vous avez demandé. P>
La méthode La deuxième façon, vous en boucle par ellementat () code> est O (n), à moins que la classe de béton réelle que le ienumerable code> représente l'optimise. Cela signifie que chaque fois que vous l'appelez, il doit boucler à travers l'entièrement en-témoine de trouver l'élément à n code>. Sans oublier que depuis que vous avez i code> boucle, il boucle de gotta à travers l'ensemble dénombrable chaque fois que pour obtenir ce compter. p>
résultat code> exactement une fois. p>
Comme ils disent que c'est d'une jointure, je suppose que ce résultat () est réellement transformé en un compteur SQL (*) code>. Presque une amélioration cependant!
Si je devais endommager une supposition, le résultat.Count () est non différé et frappe réellement la base de données alors que le forach n'est pas. Si vous retournez l'ordre, vous pouvez obtenir le résultat opposé. Aussi, vous pouvez simplement faire total = résultat.sum (); code> p>
Le premier peut être équivalent à: ou il pourrait même être équivalent à: p> ou cela pourrait même demander à obtenir d'autre part, résultat code> chaque fois qu'il appaire dans le code ci-dessus. p> comptez () code> pourrait être obtenu em> par un accès de propriété, et ollementat () code> pourrait être O (1), si ceux-ci sont sauvegardés sur des structures permettant une telle optimisation, et une telle optimisation était en effet disponible (par exemple, c'est pour Liste
C'est tout sur la compréhension de l'exécution différée! Lorsqu'une requête est exécutée plusieurs fois, le temps de fonction augmente considérablement. LINQ peut être plus rapide, mais vous devez vraiment faire un choix en fonction de la façon dont vous allez utiliser vos résultats de requête. P>
Jetez un oeil à cet article http://allthingscs.blogspot.com/ 2011/03 / linq-Performance.html . Il analyse cette question très problématique. P>
Quel touriste est la différence (ce qui est plus rapide)?
Count () Code> ira déterrer sur le tout en-téméride. Chaqueellementat (n) code> irate to the nth élément.TRANCHACH CODE> ITERA ITERA TOUT ENUDE ENUMERABLE une fois. Je ne connais pas toutes les optimisations si l'énumérable est également uniList code> ouicollection code>.Vous devriez clairement indiquer quelle méthode était plus rapide