Domanda

Ho appena sostituito questo pezzo di codice:

foreach( var source in m_sources )
{
    if( !source.IsExhausted )
    {
        ....
    }
}

con questo:

foreach( var source in m_sources.Where( src => !src.IsExhausted ) )
{
   ...
}

Ora il codice sembra migliore (per me), ma mi chiedo che cosa sta realmente accadendo qui. Sono preoccupato per le prestazioni in questo caso, e sarebbe una cattiva notizia se l'applicazione di questo filtro significherebbe che una sorta di magia compilatore avrebbe avuto luogo.

sono i due pezzi di codice facendo fondamentalmente la 'stessa' cosa? Sono contenitori temporanei creati per fare il filtraggio poi passarli al mio foreach?

Qualsiasi aiuto su questo argomento sarà più o meno apprezzato. Grazie.

È stato utile?

Soluzione

Il yield return parola chiave e lambda non comportano la creazione di classi nascoste in fase di compilazione e l'assegnazione di oggetti extra in fase di esecuzione, e se il vostro sfondo è in C o C ++, allora è naturale essere preoccupati per le prestazioni.

naturale, ma sbagliato!

Ho provato misurare l'overhead per lambda con chiusura sopra variabili locali, e c'è sembrato così incredibilmente piccole (una questione di nanosecondi) che sarebbe di alcun significato in quasi tutte le applicazioni.

Altri suggerimenti

Dipende dal tipo se m_sources.

Se si tratta di un contesto dati da LINQ to SQL o Entity Framework l'argomento che si passa è compilato come un esempio di espressione e analizzato per creare SQL (con l'aiuto del modello di dati). Ci sono alcuni costi reali in questo processo, ma probabilmente (nella maggior parte dei casi) ad essere dominato da viaggio di andata al database.

Se è IEnumerable quindi dove è più o meno implementato come:

public static IEnumnerable<T> Where(this IEnumerable<T> input, Func<T, bool> predicate) {
  foreach (var v in input) {
    if (predicate(v)) {
      yield return v;
    }
  }
}

che è abbastanza efficiente ed esegue pigramente (quindi se si rompe fuori del vostro ciclo presto il predicato non sarà applicato a tutta la collezione).

In sostanza, sì, è lo stesso, O (n).

La clausola where sarà eseguito mentre si ciclo attraverso la vostra lista (vale a dire se si rompe dopo il primo elemento, non verrà verificato le seguenti voci).

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