Basicamente, como afirma a pergunta ... a ordem das funções do LINQ é importante em termos de desempenho ? Obviamente, os resultados ainda teriam que ser idênticos ...
Exemplo:
myCollection.OrderBy(item => item.CreatedDate).Where(item => item.Code > 3);
myCollection.Where(item => item.Code > 3).OrderBy(item => item.CreatedDate);
Ambos retornam os mesmos resultados, mas estão em uma ordem LINQ diferente. Sei que reordenar alguns itens resultará em resultados diferentes, e não estou preocupado com isso. Minha principal preocupação é saber se, ao obter os mesmos resultados, o pedido pode impactar o desempenho. E, não apenas nas 2 chamadas LINQ que fiz (OrderBy, Where), mas em quaisquer chamadas LINQ.
c#
performance
linq
Michael
fonte
fonte
var query = myCollection.OrderBy(item => item.Code).Where(item => item.Code == 3);
.Respostas:
Dependerá do provedor LINQ em uso. Para o LINQ to Objects, isso certamente faria uma grande diferença. Suponha que realmente temos:
Que requer a toda coleção a ser classificada e , em seguida, filtrada. Se tivéssemos um milhão de itens, dos quais apenas um tivesse um código maior que 3, estaríamos perdendo muito tempo solicitando resultados que seriam jogados fora.
Compare isso com a operação reversa, filtrando primeiro:
Desta vez, estamos apenas ordenando os resultados filtrados, que no caso de exemplo de "apenas um único item correspondendo ao filtro" será muito mais eficiente - tanto no tempo quanto no espaço.
Também pode fazer diferença se a consulta é executada corretamente ou não. Considerar:
Tudo bem - sabemos que nunca dividiremos por 0. Mas se realizarmos a ordenação antes da filtragem, a consulta lançará uma exceção.
fonte
Sim.
Mas exatamente qual é a diferença de desempenho depende de como a árvore de expressão subjacente é avaliada pelo provedor LINQ.
Por exemplo, sua consulta pode executar mais rápido na segunda vez (com a cláusula WHERE primeiro) para LINQ-to-XML, mas mais rápido na primeira vez para LINQ-to-SQL.
Para descobrir precisamente qual é a diferença de desempenho, você provavelmente desejará criar um perfil de seu aplicativo. Como sempre, porém, a otimização prematura geralmente não vale o esforço - você pode descobrir que outros problemas além do desempenho do LINQ são mais importantes.
fonte
No seu exemplo específico, pode fazer diferença no desempenho.
Primeira consulta: sua
OrderBy
chamada precisa iterar por toda a sequência de origem, incluindo os itens em queCode
é 3 ou menos. AWhere
cláusula também precisa iterar toda a sequência ordenada.Segunda consulta: A
Where
chamada limita a sequência apenas aos itens em queCode
é maior que 3. AOrderBy
chamada então só precisa percorrer a sequência reduzida retornada pelaWhere
chamada.fonte
No Linq-To-Objects:
A classificação é bastante lenta e usa
O(n)
memória.Where
por outro lado, é relativamente rápido e usa memória constante. Fazendo assimWhere
primeiro será mais rápido e, para grandes coleções, significativamente mais rápido.A pressão de memória reduzida também pode ser significativa, uma vez que as alocações no heap de objeto grande (junto com sua coleção) são relativamente caras na minha experiência.
fonte
Observe que isso não é realmente verdade - em particular, as duas linhas a seguir fornecerão resultados diferentes (para a maioria dos provedores / conjuntos de dados):
fonte
É importante observar que você deve ter cuidado ao considerar como otimizar uma consulta LINQ. Por exemplo, se você usar a versão declarativa do LINQ para fazer o seguinte:
Se, por algum motivo, você decidisse "otimizar" a consulta armazenando a média em uma variável primeiro, não obteria os resultados desejados:
Não sei que muitas pessoas usam LINQ declarativo para objetos, mas é um bom alimento para reflexão.
fonte
Depende da relevância. Suponha que se você tiver muito poucos itens com Código = 3, o próximo pedido funcionará em um pequeno conjunto de coleta para obter o pedido por data.
Considerando que, se você tiver muitos itens com a mesma CreatedDate, o próximo pedido funcionará em um conjunto maior de coleta para obter o pedido por data.
Portanto, em ambos os casos, haverá uma diferença no desempenho
fonte