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

Esta función se llama muchas veces, por ejemplo, 1000 veces y hay 5000 estudiantes en el conjunto de resultados. ¿Cómo puedo optimizar esta función? Sé que la conversión de IEnumerable a HashSet está causando muchos gastos generales. ToHashSet es mi método de extensión. Esta función es reducir la velocidad y consumir mucho tiempo.Optimizar la conversión de IEnumerable a HashSet en LINQ

+0

¿Qué hace ToHastSet? – Turbot

+0

agregado aHashSet ... el hashset es un código de Internet. – abbas

Respuesta

9

En primer lugar, no es necesario enumerar los valores hashset en sus utilidades funcionan se podría mejorar la eficiencia mediante el uso de buena clase de extensión estática escrito por @ Jon

Converting linq result to hashset

y yo le parece don No es necesario verificar el FirstOrDefault ya que la extensión manejará el nuevo objeto de estudiante dado T para que pueda cambiar a una manera más limpia y ordenada.

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

La otra opción es que usted puede pasar IEnumerable en su constructor para HashSet como

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

lo que sólo tiene una línea de código en su función GetStudents

+0

Pero, ¿esto aumentaría el rendimiento ...? Porque hacer un nuevo hashset para valores grandes está disminuyendo el rendimiento – abbas

+0

Hashset (T) proporciona una operación de conjunto de alto rendimiento. No estoy seguro de a qué se refiere sobre el rendimiento, pero ciertamente la optimización es evitar llamadas duplicadas de la enumeración para su conversión en LINQ. – Turbot

4

no corren la consulta dos veces por llamada.

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

Su condición es innecesaria:

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

sé que la conversión de IEnumerable en Hasset está causando una gran cantidad de los gastos generales

Eso es toro. No ha medido nada y se está engañando a sí mismo para optimizar la parte incorrecta del código.

+0

Su última línea es completamente cierta. El PO está haciendo suposiciones arbitrarias. – usr