Ho bisogno di iterare e contare. Cosa è più veloce o preferito: ToArray () o ToList ()? [duplicare]

StackOverflow https://stackoverflow.com/questions/1826658

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?

È stato utile?

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 < > ;?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top