Recentemente, comecei a usar bastante o LINQ e não vi nenhuma menção à complexidade do tempo de execução para nenhum dos métodos do LINQ. Obviamente, há muitos fatores em jogo aqui, então vamos restringir a discussão ao IEnumerable
provedor LINQ-to-Objects simples . Além disso, vamos supor que qualquer Func
passado como um seletor / mutador / etc. seja uma operação O (1) barata.
Parece evidente que todas as operações de uma só passagem ( Select
, Where
, Count
, Take/Skip
, Any/All
, etc.) vai ser O (n), uma vez que só precisa de caminhar a sequência de uma vez; embora mesmo isso esteja sujeito à preguiça.
As coisas são mais obscuras para as operações mais complexas; o conjunto-como operadores ( Union
, Distinct
, Except
, etc.) trabalho usando GetHashCode
por padrão (afaik), então parece razoável supor que eles estão usando um hash-table internamente, tornando estas operações O (n), bem como, em geral. E as versões que usam um IEqualityComparer
?
OrderBy
precisaria de uma classificação, então provavelmente estamos olhando para O (n log n). E se já estiver classificado? Que tal se eu disser OrderBy().ThenBy()
e fornecer a mesma chave para ambos?
Eu poderia ver GroupBy
(e Join
) usando classificação ou hash. Qual é?
Contains
seria O (n) em a List
, mas O (1) em a HashSet
- o LINQ verifica o contêiner subjacente para ver se ele pode acelerar as coisas?
E a verdadeira questão - até agora, tenho acreditado que as operações são eficazes. No entanto, posso apostar nisso? Os contêineres STL, por exemplo, especificam claramente a complexidade de cada operação. Há alguma garantia semelhante no desempenho do LINQ na especificação da biblioteca .NET?
Mais perguntas (em resposta aos comentários):
Não pensei muito sobre a sobrecarga, mas não esperava que houvesse muito para o simples Linq-to-Objects. O post CodingHorror está falando sobre Linq-to-SQL, onde posso entender que analisar a consulta e fazer SQL aumentaria os custos - há um custo semelhante para o provedor de objetos também? Em caso afirmativo, é diferente se você estiver usando a sintaxe declarativa ou funcional?