2012-06-28 13 views
8
public HashSet<Student> GetStudents(int studentId) 
{ 
    IEnumerable<Student> studentTypes = this.studentTypes .Where(x => (x.studentID== studentId)); 
    if (studentTypes .FirstOrDefault() != null) 
    { 

     //return new HashSet<Student>(studentTypes); 
     return studentTypes.ToHashSet(); 
    } 
    else 
    { 
     return new HashSet<Student>(); 
    } 
} 

public static class LinqUtilities 
{ 
    public static HashSet<T> ToHashSet<T>(this IEnumerable<T> enumerable) 
    { 
     HashSet<T> hashSet = new HashSet<T>(); 

     foreach (var en in enumerable) 
     { 
      hashSet.Add(en); 
     } 

     return hashSet; 
    } 
} 

Questa funzione è chiamata sacco di volte dire 1000 volte e ci sono 5000 studenti nel set di risultati. Come ottimizzare questa funzione ... So che la conversione da IEnumerable a HashSet sta causando un sacco di spese generali. ToHashSet è il mio metodo di estensione. Questa funzione rallenta e consuma molto tempo.Ottimizzare IEnumerable a HashSet conversione in LINQ

+0

Che cosa fa ToHastSet? – Turbot

+0

aggiunto aHashSet ... l'hashset è un codice da Internet. – abbas

risposta

9

In primo luogo, non è necessario enumerare i valori HashSet nella vostra utilità funzionano si potrebbe migliorare l'efficienza utilizzando bella classe di estensione statica scritto da @ Jon

Converting linq result to hashset

e io pensi don È necessario controllare il FirstOrDefault poiché l'estensione gestirà il nuovo oggetto studente dato T in modo da poter passare a un modo più pulito e ordinato.

IEnumerable<Student> studentTypes = this.studentTypes.Where(x => (x.studentID== studentId)); 
return studentTypes.toHashSet(); 

L'altra opzione è che si può passare da voi IEnumerable nel vostro costruttore per HashSet come

HashSet<Student> studentTypes = new HashSet<Student>(this.studentTypes.Where(x => (x.studentID== studentId))); 

modo da avere solo una riga di codice nella funzione GetStudents

+0

Ma questo aumenterebbe le prestazioni ... perché fare un nuovo hashset per valori elevati sta riducendo le prestazioni – abbas

+0

Hashset (T) fornisce automaticamente prestazioni elevate. Non sono sicuro di ciò che si riferisce alle prestazioni, ma certamente l'ottimizzazione è di evitare la duplicazione della chiamata dell'enumerazione per la conversione in LINQ. – Turbot

4

Non eseguire la query due volte per chiamata.

//sets up a deferred query. This query will be "executed" when enumerated. 
IEnumerable<Student> studentTypes = this.studentTypes 
    .Where(x => (x.studentID== studentId)); 

//enumeration #1 (stops on first hit) 
if (studentTypes .FirstOrDefault() != null) 
{ 
    //enumeration #2 
    return studentTypes.ToHashSet(); 

la sua condizione è inutile:

//sets up a deferred query. This query will be "executed" when enumerated. 
IEnumerable<Student> studentTypes = this.studentTypes 
    .Where(x => (x.studentID== studentId)); 

//enumeration #1 
return studentTypes.ToHashSet(); 

So che la conversione da IEnumerable a Hasset sta causando un sacco delle spese generali

Ecco toro. Non hai misurato nulla e stai ingannando te stesso per ottimizzare la parte sbagliata del codice.

+0

L'ultima riga è interamente vera. Il PO sta facendo ipotesi arbitrarie. – usr