2009-03-23 39 views
27

Tôi đang xem qua danh sách chung để tìm các mục dựa trên một tham số nhất định.Danh sách chung FindAll() và foreach

Nói chung, việc triển khai tốt nhất và nhanh nhất là gì?
1. Looping qua từng mục trong danh sách và tiết kiệm mỗi trận đấu vào một danh sách mới và trở về mà

foreach(string s in list) 
{ 
    if(s == "match") 
    { 
     newList.Add(s); 
    } 
} 

return newList; 

Hoặc
2. Sử dụng phương pháp FindAll và đi qua nó một đại biểu.

newList = list.FindAll(delegate(string s){return s == "match";}); 

Cả hai đều không chạy trong ~ O (N)? Thực hành tốt nhất ở đây là gì?

Kính trọng, Jonathan

Trả lời

41

Bạn chắc chắn nên sử dụng phương pháp FindAll hoặc phương pháp LINQ tương đương. Ngoài ra, hãy cân nhắc sử dụng lambda súc tích hơn thay cho người được ủy quyền nếu bạn có thể (yêu cầu C# 3).0):

var list = new List<string>(); 
var newList = list.FindAll(s => s.Equals("match")); 
9

tôi sẽ sử dụng FindAll method trong trường hợp này, vì nó ngắn gọn hơn, và IMO, có khả năng đọc dễ dàng hơn.

Bạn có phải là họ đang khá nhiều sẽ cho cả hai thực hiện trong thời gian O (N) thời gian, mặc dù foreach statementnên được hơi nhanh cho nó không nhất thiết phải thực hiện một invocation đại biểu (đại biểu phải chịu một chút trên không như phương pháp gọi trực tiếp).

tôi phải nhấn mạnh cách đáng kể sự khác biệt này là, nó là nhiều hơn khả năng không bao giờ để tạo sự khác biệt, trừ khi bạn đang làm một lớn số hoạt động trên một danh sách lớn.

Như mọi khi, hãy kiểm tra xem nút thắt cổ chai đang ở đâu và hành động phù hợp.

4

Danh sách.FindAll là O (n) và sẽ tìm kiếm toàn bộ danh sách.

Nếu bạn muốn chạy trình vòng lặp của riêng bạn với foreach, tôi khuyên bạn nên sử dụng báo cáo lợi nhuận và trả về một IEnumerable nếu có thể. Bằng cách này, nếu bạn chỉ cần một phần tử của bộ sưu tập của bạn, nó sẽ nhanh hơn (vì bạn có thể ngăn chặn người gọi của bạn mà không làm cạn kiệt toàn bộ bộ sưu tập).

Nếu không, hãy liên kết với giao diện BCL.

3

Bất kỳ sự khác biệt hoàn hảo nào sẽ cực kỳ nhỏ. Tôi sẽ đề nghị FindAll cho rõ ràng, hoặc, nếu có thể, Enumerable.Where. Tôi thích sử dụng các phương thức Enumerable vì nó cho phép linh hoạt hơn trong việc tái cấu trúc mã (bạn không phụ thuộc vào List<T>).

5

Jonathan,

Một câu trả lời tốt, bạn có thể tìm đến đây là trong chương 5 (cân nhắc hiệu suất) của Linq To Action.

Chúng đo lường cho mỗi tìm kiếm thực hiện khoảng 50 lần và điều đó xuất hiện với foreach = 68ms mỗi chu kỳ/List.FindAll = 62ms mỗi chu kỳ. Thực sự, có lẽ bạn sẽ chỉ muốn tạo một bài kiểm tra và tự mình xem.

2

Có, cả hai triển khai đều là O (n). Họ cần phải xem xét mọi yếu tố trong danh sách để tìm tất cả các kết quả phù hợp. Về khả năng đọc, tôi cũng thích FindAll hơn. Để xem xét hiệu suất, hãy xem LINQ in Action (Ch 5.3). Nếu bạn đang sử dụng C# 3.0, bạn cũng có thể áp dụng một biểu thức lambda. Nhưng đó mới chỉ là đóng băng trên bánh:

var newList = aList.FindAll(s => s == "match"); 
1

Im với Lambdas

List<String> newList = list.FindAll(s => s.Equals("match")); 
0

Trừ khi C# đội đã được cải thiện hiệu suất cho LINQFindAll, bài viết sau đây dường như cho thấy forforeach sẽ hoạt động tốt hơn LINQFindAll về điều tra đối tượng: LINQ on Objects Performance.

Artilce này có từ tháng 3 năm 2009, ngay trước khi bài đăng này được yêu cầu ban đầu.

Các vấn đề liên quan