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

Chức năng này được gọi là rất nhiều lần cho 1000 lần và có 5000 học sinh trong tập kết quả. Làm cách nào để tối ưu hóa chức năng này ... Tôi biết rằng việc chuyển đổi từ IEnumerable sang HashSet đang gây ra rất nhiều chi phí. ToHashSet là phương pháp tiện ích mở rộng của tôi. Chức năng này làm chậm và ăn nhiều thời gian.Tối ưu hóa IEnumerable thành chuyển đổi HashSet trong LINQ

+0

ToHastSet làm gì? – Turbot

+0

đã thêm vàoHashSet ... mã băm là mã từ internet. – abbas

Trả lời

9

Trước tiên, bạn không cần phải liệt kê các giá trị HashSet trong tiện ích của bạn hoạt động bạn có thể cải thiện hiệu quả bằng cách sử dụng thoải mái lớp mở rộng tĩnh được viết bởi @ Jon

Converting linq result to hashset

và tôi nghĩ rằng bạn don 't cần phải kiểm tra trên FirstOrDefault kể từ khi phần mở rộng sẽ xử lý các đối tượng sinh viên mới được đưa ra T vì vậy bạn có thể thay đổi để sạch sẽ hơn và cách gọn gàng.

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

Các tùy chọn khác là bạn có thể vượt qua bạn IEnumerable vào constructor của bạn cho HashSet như

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

vì vậy bạn chỉ có một dòng mã trong chức năng GetStudents bạn

+0

Nhưng điều này sẽ tăng hiệu suất .. ?? beacuse làm hashset mới cho các giá trị lớn là giảm hiệu suất – abbas

+0

Hashset (T) nó tự cung cấp hoạt động thiết lập hiệu suất cao. Tôi không chắc chắn những gì bạn giới thiệu về hiệu suất nhưng chắc chắn tối ưu hóa là để tránh cuộc gọi trùng lặp của các liệt kê cho chuyển đổi của bạn trong LINQ. – Turbot

4

Đừng chạy truy vấn hai lần cho mỗi cuộc gọi.

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

tình trạng của bạn là không cần thiết:

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

Tôi biết rằng việc chuyển đổi từ IEnumerable để Hasset đang gây ra rất nhiều của các chi phí

Đó là con bò. Bạn đã đo lường không có gì và đang gây hiểu lầm cho chính mình để tối ưu hóa phần sai của mã.

+0

Dòng cuối cùng của bạn là hoàn toàn đúng sự thật. OP đang đưa ra các giả định tùy ý. – usr