Fondamentalement, comme l'indique la question ... l'ordre des fonctions LINQ est-il important en termes de performances ? Évidemment, les résultats devraient encore être identiques ...
Exemple:
myCollection.OrderBy(item => item.CreatedDate).Where(item => item.Code > 3);
myCollection.Where(item => item.Code > 3).OrderBy(item => item.CreatedDate);
Les deux me renvoient les mêmes résultats, mais sont dans un ordre LINQ différent. Je me rends compte que la réorganisation de certains éléments entraînera des résultats différents, et je ne suis pas préoccupé par ceux-ci. Ma principale préoccupation est de savoir si, en obtenant les mêmes résultats, la commande peut avoir un impact sur les performances. Et, pas seulement sur les 2 appels LINQ que j'ai passés (OrderBy, Where), mais sur tous les appels LINQ.
c#
performance
linq
Michael
la source
la source
var query = myCollection.OrderBy(item => item.Code).Where(item => item.Code == 3);
.Réponses:
Cela dépendra du fournisseur LINQ utilisé. Pour LINQ to Objects, cela pourrait certainement faire une énorme différence. Supposons que nous ayons réellement:
Cela nécessite que toute la collection soit triée puis filtrée. Si nous avions un million d'articles, dont un seul avait un code supérieur à 3, nous perdrions beaucoup de temps à commander des résultats qui seraient jetés.
Comparez cela avec l'opération inversée, en filtrant d'abord:
Cette fois, nous ne commandons que les résultats filtrés, ce qui dans le cas de l'exemple "un seul élément correspondant au filtre" sera beaucoup plus efficace - à la fois dans le temps et dans l'espace.
Cela peut également faire une différence dans l'exécution correcte ou non de la requête. Considérer:
C'est bien - nous savons que nous ne diviserons jamais par 0. Mais si nous effectuons le tri avant le filtrage, la requête lèvera une exception.
la source
Oui.
Mais exactement ce que la différence de performance est dépend de la façon dont l'arbre d'expression sous - jacente est évaluée par le fournisseur de LINQ.
Par exemple, votre requête peut s'exécuter plus rapidement la deuxième fois (avec la clause WHERE en premier) pour LINQ-to-XML, mais plus rapidement la première fois pour LINQ-to-SQL.
Pour connaître précisément la différence de performances, vous souhaiterez probablement profiler votre application. Comme toujours avec de telles choses, cependant, l'optimisation prématurée ne vaut généralement pas la peine - vous pouvez très bien constater que des problèmes autres que les performances LINQ sont plus importants.
la source
Dans votre exemple particulier, cela peut faire une différence sur la performance.
Première requête: votre
OrderBy
appel doit parcourir toute la séquence source, y compris les éléments dont la valeurCode
est égale ou inférieure à 3. LaWhere
clause doit alors également itérer toute la séquence ordonnée.Deuxième requête: l'
Where
appel limite la séquence aux seuls éléments oùCode
est supérieur à 3. L'OrderBy
appel n'a alors besoin que de parcourir la séquence réduite renvoyée par l'Where
appel.la source
Dans Linq-To-Objects:
Le tri est plutôt lent et utilise de la
O(n)
mémoire.Where
d'autre part est relativement rapide et utilise une mémoire constante. Donc, faire enWhere
premier sera plus rapide et beaucoup plus rapide pour les grandes collections.La pression mémoire réduite peut également être importante, car les allocations sur le tas d'objets volumineux (ainsi que leur collection) sont relativement coûteuses d'après mon expérience.
la source
Notez que ce n'est pas réellement vrai - en particulier, les deux lignes suivantes donneront des résultats différents (pour la plupart des fournisseurs / ensembles de données):
la source
Il est intéressant de noter que vous devez être prudent lors de l' examen comment optimiser une requête LINQ. Par exemple, si vous utilisez la version déclarative de LINQ pour effectuer les opérations suivantes:
Si, pour une raison quelconque, vous décidiez «d'optimiser» la requête en stockant d'abord la moyenne dans une variable, vous n'obtiendrez pas les résultats souhaités:
Je sais que peu de gens utilisent LINQ déclaratif pour les objets, mais c'est une bonne matière à réflexion.
la source
Cela dépend de la pertinence. Supposons que si vous avez très peu d'articles avec Code = 3, la commande suivante fonctionnera sur un petit ensemble de collections pour obtenir la commande par date.
Alors que si vous avez de nombreux articles avec la même date de création, la prochaine commande fonctionnera sur un plus grand ensemble de collections pour obtenir la commande par date.
Donc, dans les deux cas, il y aura une différence de performance
la source