Je peux trier une liste en utilisant Trier ou Trier par. Lequel est le plus rapide? Les deux travaillent-ils sur le même algorithme?
List<Person> persons = new List<Person>();
persons.Add(new Person("P005", "Janson"));
persons.Add(new Person("P002", "Aravind"));
persons.Add(new Person("P007", "Kazhal"));
1.
persons.Sort((p1,p2)=>string.Compare(p1.Name,p2.Name,true));
2.
var query = persons.OrderBy(n => n.Name, new NameComparer());
class NameComparer : IComparer<string>
{
public int Compare(string x,string y)
{
return string.Compare(x, y, true);
}
}
c#
.net
performance
sorting
sql-order-by
user215675
la source
la source
Réponses:
Pourquoi ne pas le mesurer:
Sur mon ordinateur, une fois compilé en mode Release, ce programme imprime:
METTRE À JOUR:
Comme suggéré par @Stefan, voici les résultats du tri d'une grande liste moins de fois:
Impressions:
Dans ce scénario, il semble que OrderBy fonctionne mieux.
UPDATE2:
Et en utilisant des noms aléatoires:
Où:
Rendements:
Still OrderBy est plus rapide
la source
LINQ
doit dépenser de la mémoire supplémentaire par rapport à une mise enList<T>.Sort
œuvre en place . Je ne suis pas sûr qu'ils aient amélioré cela dans les nouvelles versions .NET, mais sur ma machine (version i7 3ème génération 64 bits .NET 4.5), lesSort
performances sont supérieuresOrderBy
dans tous les cas. De plus, en regardantOrderedEnumerable<T>
le code source, il semble qu'il crée trois tableaux supplémentaires (d'abord aBuffer<T>
, puis un tableau de clés projetées, puis un tableau d'indices) avant d'appeler enfin Quicksort pour trier le tableau d'indices en place.ToArray
appel qui crée le tableau résultant. Les opérations de mémoire et l'indexation de tableau sont des opérations incroyablement rapides, mais je ne trouve toujours pas la logique derrière ces résultats.Non, ce n'est pas le même algorithme. Pour commencer, le LINQ
OrderBy
est documenté comme stable (c'est-à-dire que si deux éléments ont le mêmeName
, ils apparaîtront dans leur ordre d'origine).Cela dépend également de la mise en mémoire tampon de la requête ou de l'itération plusieurs fois (LINQ-to-Objects, à moins que vous ne tamponniez le résultat, sera réorganisé par
foreach
).Pour la
OrderBy
requête, je serais également tenté d'utiliser:(pour l'
{yourchoice}
un desCurrentCulture
,Ordinal
ouInvariantCulture
).List<T>.Sort
Enumerable.OrderBy
la source
Enumerable.OrderBy
et explorer son implémentation interne, vous pouvez voir que l'algorithme de tri OrderBy est une variante de QuickSort qui effectue un tri stable. (VoirSystem.Linq.EnumerableSorter<TElement>
). Ainsi,Array.Sort
etEnumerable.OrderBy
peut à la fois s'attendre à ce que O (N log N) temps d'exécution, où N est le nombre d'éléments de la collection.La réponse de Darin Dimitrov montre que
OrderBy
c'est légèrement plus rapide queList.Sort
face à des entrées déjà triées. J'ai modifié son code pour qu'il trie à plusieurs reprises les données non triées, etOrderBy
est dans la plupart des cas légèrement plus lent.De plus, le
OrderBy
test utiliseToArray
pour forcer l'énumération de l'énumérateur Linq, mais cela renvoie évidemment un type (Person[]
) qui est différent du type d'entrée (List<Person>
). J'ai donc relancé le test en utilisantToList
plutôt queToArray
et j'ai obtenu une différence encore plus grande:Le code:
la source
OrderByWithToList
prend le même temps queOrderBy
.Je pense qu'il est important de noter une autre différence entre
Sort
etOrderBy
:Supposons qu'il existe un
Person.CalculateSalary()
méthode qui prend beaucoup de temps; peut-être même plus que l'opération consistant à trier une grande liste.Comparer
L'option 2 peut avoir des performances supérieures, car elle n'appelle la
CalculateSalary
méthode que n fois, alors que l'Sort
option peut appelerCalculateSalary
jusqu'à 2 n fois log ( n ) , en fonction du succès de l'algorithme de tri.la source
n
times. Ce n'est évidemment pas aussi pratique que d'utiliser OrderBy.En un mot :
Trier par liste / tableau ():
OrderBy / ThenBy ():
x => x.Id
. Toutes les clés sont extraites avant le tri. Cela peut entraîner de meilleures performances que l'utilisation de Sort () et d'un comparateur personnalisé.Sources: MDSN , source de référence et référentiel dotnet / coreclr (GitHub).
Certaines des instructions répertoriées ci-dessus sont basées sur l'implémentation actuelle du framework .NET (4.7.2). Cela pourrait changer à l'avenir.
la source
vous devez calculer la complexité des algorithmes utilisés par les méthodes OrderBy et Sort. QuickSort a une complexité de n (log n) comme je me souviens, où n est la longueur du tableau.
J'ai aussi recherché orderby, mais je n'ai trouvé aucune information, même dans la bibliothèque msdn. si vous n'avez pas les mêmes valeurs et le tri lié à une seule propriété, je préfère utiliser la méthode Sort (); sinon, utilisez OrderBy.
la source
Je veux juste ajouter que orderby est bien plus utile.
Pourquoi? Parce que je peux faire ceci:
Pourquoi un comparateur compliqué? Triez simplement en fonction d'un champ. Ici, je trie en fonction de TotalBalance.
Très facile.
Je ne peux pas faire ça avec tri. Je me demande pourquoi. Faites bien avec orderBy.
Quant à la vitesse, c'est toujours O (n).
la source