Posso classificar uma lista usando Sort ou OrderBy. Qual é mais rápido? Ambos estão trabalhando no mesmo algoritmo?
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
fonte
fonte
Respostas:
Por que não medir:
No meu computador, quando compilado no modo Release, este programa imprime:
ATUALIZAR:
Conforme sugerido por @Stefan, aqui estão os resultados de classificar uma lista grande menos vezes:
Impressões:
Nesse cenário, parece que o desempenho de OrderBy é melhor.
ATUALIZAÇÃO2:
E usando nomes aleatórios:
Onde:
Rendimentos:
Ainda assim, OrderBy é mais rápido
fonte
LINQ
tem que gastar memória adicional em comparação com umaList<T>.Sort
implementação no local . Não tenho certeza se eles melhoraram isso nas versões mais recentes do .NET, mas na minha máquina (versão i7 do .NET 4.5 de 64 bits de 3ª geração)Sort
superaOrderBy
em todos os casos. Além disso, ao observar oOrderedEnumerable<T>
código-fonte, parece que ele cria três matrizes adicionais (primeiro aBuffer<T>
, depois uma matriz de chaves projetadas e, em seguida, uma matriz de índices) antes de finalmente chamar o Quicksort para classificar a matriz de índices no lugar.ToArray
chamada que cria o array resultante. Operações de memória e indexação de array são operações incrivelmente rápidas, mas ainda não consigo encontrar a lógica por trás desses resultados.Não, eles não são o mesmo algoritmo. Para começar, o LINQ
OrderBy
é documentado como estável (ou seja, se dois itens tiverem o mesmoName
, eles aparecerão em sua ordem original).Também depende de você armazenar em buffer a consulta em vez de iterá-la várias vezes (LINQ-to-Objects, a menos que você armazene o resultado em buffer, será reordenado por
foreach
).Para a
OrderBy
consulta, também ficaria tentado a usar:(para
{yourchoice}
um deCurrentCulture
,Ordinal
ouInvariantCulture
).List<T>.Sort
Enumerable.OrderBy
fonte
Enumerable.OrderBy
e detalhar sua implementação interna, poderá ver que o algoritmo de classificação OrderBy é uma variante do QuickSort que faz uma classificação estável. (VejaSystem.Linq.EnumerableSorter<TElement>
.) Assim,Array.Sort
eEnumerable.OrderBy
pode-se esperar que ambos tenham O (N log N) tempos de execução, onde N é o número de elementos na coleção.A resposta de Darin Dimitrov mostra que isso
OrderBy
é um pouco mais rápido do queList.Sort
quando confrontado com uma entrada já classificada. Modifiquei seu código para que classifique repetidamente os dados não classificados e,OrderBy
na maioria dos casos, é um pouco mais lento.Além disso, o
OrderBy
teste usaToArray
para forçar a enumeração do enumerador Linq, mas isso obviamente retorna um tipo (Person[]
) que é diferente do tipo de entrada (List<Person>
). Portanto, executei novamente o teste usando emToList
vez deToArray
e obtive uma diferença ainda maior:O código:
fonte
OrderByWithToList
leva o mesmo tempo queOrderBy
.Acho importante notar outra diferença entre
Sort
eOrderBy
:Suponha que exista um
Person.CalculateSalary()
método que leve muito tempo; possivelmente mais do que a operação de classificação de uma grande lista.Comparar
A opção 2 pode ter desempenho superior, pois chama o
CalculateSalary
método apenas n vezes, enquanto aSort
opção pode chamarCalculateSalary
até 2 n log ( n ) vezes, dependendo do sucesso do algoritmo de ordenação.fonte
n
times. Obviamente, isso não é tão conveniente quanto usar OrderBy.Resumindo:
Classificar por lista / matriz ():
OrderBy / ThenBy ():
x => x.Id
:). Todas as chaves são extraídas antes da classificação. Isso pode resultar em melhor desempenho do que usar Sort () e um comparador personalizado.Fontes: MDSN , fonte de referência e repositório dotnet / coreclr (GitHub).
Algumas das declarações listadas acima são baseadas na implementação atual do .NET framework (4.7.2). Isso pode mudar no futuro.
fonte
você deve calcular a complexidade dos algoritmos usados pelos métodos OrderBy e Sort. QuickSort tem uma complexidade de n (log n), como me lembro, onde n é o comprimento da matriz.
Também procurei o Orderby's, mas não consegui encontrar nenhuma informação, mesmo na biblioteca do msdn. se você não tiver os mesmos valores e classificação relacionada a apenas uma propriedade, prefiro usar o método Sort (); se não, use OrderBy.
fonte
Só quero acrescentar que o pedido por é muito mais útil.
Por quê? Porque eu posso fazer isso:
Por que comparador complicado? Basta classificar com base em um campo. Aqui estou classificando com base no TotalBalance.
Muito fácil.
Eu não posso fazer isso com sorte. Eu quero saber porque. Faça bem com orderBy.
Quanto à velocidade, é sempre O (n).
fonte