Có bao giờ bạn thắc mắc Any
, Contains
hay Exists
nên dùng cái nào không, sao phải "đẻ" ra 3 thằng vậy nhỉ! Bây giờ cùng mình coi thử tại sao nha. Let's go!
Dùng cái nào?
Khi làm việc với List<T>, IEnumerable<T> hoặc array, việc sử dụng phương thức Contains
sẽ tận dụng tối đa hiệu quả của chúng nhờ vào cách chúng được thiết kế bên trong (tìm kiếm bằng tuyến tính dựa vào index, dùng vòng lặp for cơ bản), đảm bảo hiệu suất cao nhất.
Còn với Exists
, chúng ta chỉ có thể dùng với List<T> hoặc mảng. Với cơ chế tìm kiếm tuyến tính như trên nhưng bây giờ nhận vào tham số là một delegate để check điều kiện (enumerator), điều này dẫn đến tốc độ sẽ chậm hơn so với Contains
.
Ngược lại, phương thức Any
của LINQ có thể áp dụng cho mọi kiểu IEnumerable<T> (List<T> kế thừa từ đây nên vẫn xài được, array cũng tương tự), mang lại sự linh hoạt cao.
Tuy nhiên, chính sự linh hoạt này lại khiến Any
chạy chậm hơn Exists
do phải tạo ra enumerator + xài foreach và có thêm một số chi phí khác (check điều kiện throw exception này nọ).
Cả ba có điểm chung của 3 method này là đều tìm kiếm bằng tuyến tính với độ phức tạp O(n).
Có chút lưu ý, Contains
nếu sử dụng không khéo, nhất là khi không hiểu rõ {% post_link Tham-chieu-va-tham-tri-trong-lap-trinh 'tham chiếu tham trị' %} thì dễ bị toang => không sử dụng Contains để check với list hoặc mảng kiểu object (tham chiếu). Còn với Any
, Exists
khi viết điều kiện so sánh, phần nào chúng ta đã nắm rõ đang so sánh cái gì.
Ví dụ
using System.Collections.Generic;
using System.Linq; public class Program
{ static void Main(string[] args) { var listNumber = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; listNumber.Contains(6); listNumber.Exists(a => a == 6); listNumber.Any(a => a == 6); }
}
Tóm lại
Chốt lại, nếu bạn biết rõ đang so sánh cái gì, đang so sánh giá trị, thì ưu tiên xài Contains
, còn ngược lại nếu đang xử lý List<T> hoặc mảng hãy chọn Exists
. Còn nếu bạn cần một phương thức tổng quát hơn, có thể sử dụng cho nhiều loại bộ sưu tập khác nhau, Any
sẽ là lựa chọn hợp lý.
So sánh tốc độ
Đây là so sánh tốc độ của ba thằng với nhau (list, mảng, ienumerable có 10000 phần tử kiểu int), hãy nhìn vào cột 1, 2 và 5 nhé, lấy thằng ListAny làm chuẩn: