2012-06-28 11 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; 
    } 
} 

Ta funkcja jest wywoływana wiele razy razy mówią 1000 razy i istnieje 5000 uczniów w zestawie wyników. Jak mogę zoptymalizować tę funkcję ... Wiem, że konwersja z IEnumerable na HashSet powoduje wiele kosztów ogólnych. ToHashSet jest moją metodą rozszerzenia. Ta funkcja ma spowolnić i pochłania dużo czasu.Optymalizacja konwersji IEnumerable do HashSet w LINQ

+0

Co robi ToHastSet? – Turbot

+0

dodano doHashSet ... hashset to kod z Internetu. – abbas

Odpowiedz

9

Po pierwsze, nie trzeba wyliczać wartości Hashset w narzędziowych funkcjonować można poprawić efektywne przy użyciu miły klasę wewnętrzny statyczny napisany przez @Jon

Converting linq result to hashset

i myślę, że don musisz sprawdzić FirstOrDefault, ponieważ rozszerzenie obsłuży nowy obiekt ucznia podany T , dzięki czemu możesz zmienić na bardziej czysty i uporządkowany sposób.

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

Druga opcja to można przekazać ci IEnumerable do swojego konstruktora dla HashSet jak

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

więc masz tylko jedną linię kodu w funkcji GetStudents

+0

Ale czy to zwiększy wydajność ..? Beacuse robić nowy hashset dla dużych wartości zmniejsza wydajność – abbas

+0

Hashset (T) sam zapewnia wysoką wydajność zestawu operacji. Nie jestem pewien, co mówisz o wydajności, ale z pewnością optymalizacja polega na uniknięciu duplikowania wywołania wyliczenia dla konwersji w LINQ. – Turbot

4

Nie uruchamiaj zapytanie dwa razy na połączenie.

//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(); 

Twój stan jest niepotrzebna:

//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(); 

wiem, że konwersja z IEnumerable do Hasset powoduje wiele kosztów ogólnych

to byk. Nic nie zmierzyłeś i wprowadzasz w błąd, by zoptymalizować niewłaściwą część kodu.

+0

Twoja ostatnia linia jest całkowicie prawdziwa. PO dokonuje arbitralnych założeń. – usr