2013-02-18 11 views
5

Ecco il codice estratto della funzione SingleOrDefault:ottimizzazione in funzione SingleOrDefault di Linq

public static TSource SingleOrDefault<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) { 
    if (source == null) throw Error.ArgumentNull("source"); 
    if (predicate == null) throw Error.ArgumentNull("predicate"); 
    TSource result = default(TSource); 
    long count = 0; 
    foreach (TSource element in source) { 
     if (predicate(element)) { 
      result = element; 
      checked { count++; } 
     } 
    } 
    switch (count) { 
     case 0: return default(TSource); 
     case 1: return result; 
    } 
    throw Error.MoreThanOneMatch(); 
} 

Mi chiedo di sapere se v'è alcuna ragione per cui dopo aver trovato più di un elemento nel ciclo, non ci non è un'istruzione break per impedire il loop del resto della lista. In ogni caso, si verificherà un errore. Per una grande lista in cui si trova più di un articolo all'inizio, penso che sarebbe una grande differenza.

+0

Dove si ottiene il codice? Decompilato uno? –

+0

Se osservate il sovraccarico non prendendo un predicato vedrete che è ottimizzato per IList e solo prendendo due elementi. Presumo che il caso dell'errore non sia importante per ottimizzare – adrianm

+0

@HamletHakobyan Sì, ho usato Resharper. – Samuel

risposta

7

Jon Skeet found this while reimplementing LINQ to objects as part of his EduLinq blog series:

Si scopre che in LINQ to Objects, i sovraccarichi senza un lancio InvalidOperationException predicato non appena vedono un secondo elemento, ma i sovraccarichi con un predicato continuano a iterare anche quando Ho visto un secondo elemento che corrisponde a un predicato. Questo mi sembra ridicolo incoerente: ho aperto un problema su Connect; vedremo cosa succede

Nel Connect issue in question, Microsft dire:

questo sarebbe grande per ripulire, in modo che l'iterazione l'intera sequenza non è necessaria quando si utilizza la Single overload che accetta un predicato - Potremmo fallire velocemente nel trovare una seconda corrispondenza, simile a quello che facciamo quando non viene specificato alcun predicato.

Tuttavia, poiché il beneficio perf per essere avuto qui sarebbe limitato a Single 's caso di errore, questo problema attualmente scende appena sotto il nostro bug linea di triage di taglio. Stiamo segnalando che il problema non verrà risolto per indicare che non stiamo attualmente monitorando il problema per risolvere il problema nella prossima versione di Visual Studio. Riattiveremo questo bug nel prossimo anno se otteniamo oltre le aspettative attraverso la nostra lista di triage di bug, o se rivisitiamo il bug per la seguente versione.

Questo è stato ad aprile 2011 ...

+0

Grazie mille. Dopo aver esaminato l'implementazione di Jon Skeet, dico ai miei colleghi che è l'implementazione che stavo cercando da un paio di ore. – Samuel

Problemi correlati