Với một bộ sưu tập đồ vật khổng lồ, có sự khác biệt về hiệu suất giữa các đồ vật sau đây không?
myCollection.Contains(myElement)
myCollection.Any(currentElement => currentElement == myElement)
Với một bộ sưu tập đồ vật khổng lồ, có sự khác biệt về hiệu suất giữa các đồ vật sau đây không?
myCollection.Contains(myElement)
myCollection.Any(currentElement => currentElement == myElement)
Câu trả lời:
Contains()
là một phương thức thể hiện và hiệu suất của nó phụ thuộc phần lớn vào chính bộ sưu tập. Ví dụ, Contains()
trên a List
là O (n), trong khi Contains()
trên a HashSet
là O (1).
Any()
là một phương thức mở rộng và sẽ đơn giản đi qua bộ sưu tập, áp dụng ủy nhiệm trên mọi đối tượng. Do đó, nó có độ phức tạp là O (n).
Any()
tuy nhiên, linh hoạt hơn vì bạn có thể vượt qua một đại biểu. Contains()
chỉ có thể chấp nhận một đối tượng.
Contains
cũng là một phương thức mở rộng chống lại IEnumerable<T>
(mặc dù một số tập hợp cũng có Contains
phương thức phiên bản riêng của chúng ). Như bạn nói, Any
linh hoạt hơn Contains
vì bạn có thể chuyển cho nó một vị từ tùy chỉnh, nhưng Contains
có thể nhanh hơn một chút vì nó không cần thực hiện lời gọi đại biểu cho mỗi phần tử.
All()
hoạt động tương tự.
Nó phụ thuộc vào bộ sưu tập. Nếu bạn có một bộ sưu tập có thứ tự, thì Contains
có thể thực hiện tìm kiếm thông minh (nhị phân, băm, b-tree, v.v.), trong khi với `Any (), về cơ bản bạn gặp khó khăn với việc liệt kê cho đến khi tìm thấy nó (giả sử LINQ-to-Objects) .
Cũng lưu ý rằng trong ví dụ của bạn, Any()
đang sử dụng ==
toán tử sẽ kiểm tra sự bình đẳng tham chiếu, while Contains
sẽ sử dụng IEquatable<T>
hoặc Equals()
phương thức, có thể bị ghi đè.
Tôi cho rằng điều đó sẽ phụ thuộc vào loại myCollection
quy định cách Contains()
thực hiện. Ví dụ, nếu một cây nhị phân được sắp xếp, nó có thể tìm kiếm thông minh hơn. Ngoài ra, nó có thể tính đến hàm băm của phần tử. Any()
mặt khác sẽ liệt kê thông qua tập hợp cho đến khi tìm được phần tử đầu tiên thỏa mãn điều kiện. Không có tối ưu hóa nếu đối tượng có một phương pháp tìm kiếm thông minh hơn.
Contains () cũng là một phương thức mở rộng có thể hoạt động nhanh nếu bạn sử dụng nó đúng cách. Đối với ví dụ:
var result = context.Projects.Where(x => lstBizIds.Contains(x.businessId)).Select(x => x.projectId).ToList();
Điều này sẽ cung cấp cho truy vấn
SELECT Id
FROM Projects
INNER JOIN (VALUES (1), (2), (3), (4), (5)) AS Data(Item) ON Projects.UserId = Data.Item
trong khi bất kỳ () mặt khác luôn lặp qua O (n).
Hy vọng điều này sẽ hiệu quả ....