Ho bisogno di iterare e contare. Cosa è più veloce o preferito: ToArray () o ToList ()? [duplicare]
-
22-07-2019 - |
Domanda
Possibile duplicato:
È meglio chiamare ToList () o ToArray () nelle query LINQ?
Ho un codice come questo:
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
}
quale metodo è preferito?
Potrei andare senza nessuno, ma devo conoscere le dimensioni e non voglio chiamare Enumerable.Count<T>()
- sembra che faccia più azioni di Array<T>.Size
o List<T>.Count
. Ho ragione?
Soluzione
In realtà, nell'attuale implementazione MS di Count (IEnumerable) c'è un collegamento che cerca se IEnumerable è un ICollection e chiama Count su di esso. Quindi le prestazioni dovrebbero essere comparabili per il conteggio degli elementi.
ToList e ToArray sono un po 'gli stessi. Se IEnumerable è un ICollection, viene invece chiamato il metodo CopyTo, che è un po 'più veloce.
Quindi, scegli ciò che rende il tuo codice più leggibile e fai riferimento al TUO caso d'uso per avere una risposta definitiva.
Aggiornamento: Ho fatto un punto di riferimento ingenuo.
A partire da un array: var items = Enumerable.Range(1,1000).ToArray();
- chiamando ToList (): 25ms / 10000
- chiamando ToArray (): 23 ms / 10000
A partire da un IEnumerable: var items = Enumerable.Range(1,1000);
- chiamando ToList (): 168ms / 10000
- chiamando ToArray (): 171 ms / 10000
Quindi sostanzialmente ottieni prestazioni comparabili.
Altri suggerimenti
Se sei veramente preoccupato per le prestazioni, dovresti scorrere il IEnumerable
e contarlo mentre procedi. Questo evita di dover creare una nuova raccolta del tutto e l'intersezione deve essere ripetuta una sola volta:
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;
}
Ma come ha detto qualcun altro: questo puzza di micro-ottimizzazione. Se le prestazioni contano davvero in questa situazione, almeno esegui la profilazione delle prestazioni per scoprire quale metodo è davvero il più veloce per te.
La differenza è probabilmente così piccola che vale la pena semplicemente usare il metodo che si adatta meglio alle tue esigenze. Odori di micro-ottimizzazione.
E in questo caso, dal momento che tutto ciò che stai facendo è enumerare il set e contare il set (entrambi i quali puoi fare con un IEnumerable), perché non lasciarlo semplicemente come IEnumerable < > ;?