Eu preciso para iterar e contar. O que é mais rápido ou preferencial: ToArray () ou ToList ()? [duplicado]
-
22-07-2019 - |
Pergunta
Duplicate possíveis:
É melhor ToList call () ou ToArray () em consultas LINQ?
Eu tenho um código como este:
void Foobar(string[] arr, Dictionary<string, string[]>)
{
var t = arr.Intersect(dic.Keys).ToList(); // .or ToArray() ?
foreach(var item in t)
{
..
}
var j = t.Count; // also I need this
}
que é o preferido método?
Eu poderia ir sem qualquer mas eu preciso saber o tamanho e eu não quero Enumerable.Count<T>()
chamada - parece fazer fazer mais ações, em seguida, Array<T>.Size
ou List<T>.Count
. Estou certo?
Solução
Na verdade, na implementação MS atual de Count (IEnumerable) há um atalho olhando se o IEnumerable é um ICollection e chamadas Conte com isso. Assim, o desempenho deve ser comparável para os elementos de contagem.
ToList e ToArray são um pouco o mesmo. Se o IEnumerable é um ICollection, então o método CopyTo é chamado em vez disso, que é um pouco mais rápido.
Assim, escolher o que torna seu código mais legível, e ponto de referência para seu caso de uso para ter uma resposta definitiva.
Update: Eu fiz uma referência ingênuo.
A partir de uma matriz: var items = Enumerable.Range(1,1000).ToArray();
- chamando ToList (): 25ms / 10000
- chamando ToArray (): 23 ms / 10000
A partir de um IEnumerable: var items = Enumerable.Range(1,1000);
- chamando ToList (): 168ms / 10000
- chamando ToArray (): 171 ms / 10000
Então, basicamente, você obtém um desempenho comparável.
Outras dicas
Se você é realmente preocupado com o desempenho, você deve varrer o IEnumerable
e contá-lo como você vai. Isso evita ter que criar uma nova coleção completamente, e o cruzamento só para ser repetido uma vez:
void Foobar(string[] arr, Dictionary<string, string[]>)
{
var t = arr.Intersect(dic.Keys);
int count = 0;
foreach(var item in t)
{
count++;
..
}
var j = count;
}
Mas como alguém disse: isto cheira a micro-otimização. Se o desempenho realmente importa nesta situação, pelo menos, fazer o desempenho de perfis para descobrir qual método é realmente o mais rápido para você.
A diferença é provavelmente tão pequena que cabe apenas usando o método que se adapta às suas necessidades melhor. Cheira a micro-otimização.
E, neste caso, uma vez que tudo que você está fazendo é enumerar o conjunto e contando o conjunto (ambos os quais você pode fazer com um IEnumerable), por que não deixá-lo como um IEnumerable <>?