Tôi có một lớp học, như thế này:
public class MyClass
{
public int Value { get; set; }
public bool IsValid { get; set; }
}
Trong thực tế, nó lớn hơn nhiều, nhưng điều này tái tạo vấn đề (sự kỳ lạ).
Tôi muốn lấy tổng của Value
, trong đó cá thể hợp lệ. Cho đến nay, tôi đã tìm thấy hai giải pháp cho việc này.
Cái đầu tiên là đây:
int result = myCollection.Where(mc => mc.IsValid).Select(mc => mc.Value).Sum();
Tuy nhiên, cái thứ hai là:
int result = myCollection.Select(mc => mc.IsValid ? mc.Value : 0).Sum();
Tôi muốn có được phương pháp hiệu quả nhất. Tôi, lúc đầu, nghĩ rằng cái thứ hai sẽ hiệu quả hơn. Sau đó, phần lý thuyết của tôi bắt đầu "Chà, một là O (n + m + m), phần còn lại là O (n + n). Phần đầu tiên sẽ hoạt động tốt hơn với nhiều thương binh hơn, trong khi phần thứ hai sẽ hoạt động tốt hơn với số ít". Tôi nghĩ rằng họ sẽ thực hiện như nhau. EDIT: Và sau đó @Martin đã chỉ ra rằng Vị trí và Chọn được kết hợp với nhau, vì vậy nó thực sự phải là O (m + n). Tuy nhiên, nếu bạn nhìn bên dưới, có vẻ như điều này không liên quan.
Vì vậy, tôi đưa nó vào thử nghiệm.
(Đó là hơn 100 dòng, vì vậy tôi nghĩ tốt hơn nên đăng nó dưới dạng Gist.)
Kết quả thật ... thú vị.
Với sai số ràng buộc 0%:
Các thang đo có lợi cho Select
và Where
, khoảng ~ 30 điểm.
How much do you want to be the disambiguation percentage?
0
Starting benchmarking.
Ties: 0
Where + Select: 65
Select: 36
Với dung sai cà vạt 2%:
Điều này cũng tương tự, ngoại trừ một số người trong phạm vi 2%. Tôi muốn nói rằng đó là một lỗi tối thiểu. Select
và Where
bây giờ chỉ có một dẫn ~ 20 điểm.
How much do you want to be the disambiguation percentage?
2
Starting benchmarking.
Ties: 6
Where + Select: 58
Select: 37
Với dung sai cà vạt 5%:
Đây là những gì tôi muốn nói là tỷ lệ lỗi tối đa của tôi. Nó làm cho nó tốt hơn một chút cho Select
, nhưng không nhiều.
How much do you want to be the disambiguation percentage?
5
Starting benchmarking.
Ties: 17
Where + Select: 53
Select: 31
Với dung sai cà vạt 10%:
Đây là cách thoát khỏi lỗi của tôi, nhưng tôi vẫn quan tâm đến kết quả. Bởi vì nó mang lại cho Select
và Where
hai mươi điểm dẫn đầu mà nó đã có được một thời gian.
How much do you want to be the disambiguation percentage?
10
Starting benchmarking.
Ties: 36
Where + Select: 44
Select: 21
Với dung sai cà vạt 25%:
Đây là bằng cách nào, cách ra khỏi lề của tôi về lỗi, nhưng tôi vẫn đang quan tâm đến kết quả, bởi vì Select
và Where
vẫn (gần) giữ dẫn 20 điểm của họ. Có vẻ như nó vượt xa nó trong một số ít khác biệt, và đó là điều khiến nó dẫn đầu.
How much do you want to be the disambiguation percentage?
25
Starting benchmarking.
Ties: 85
Where + Select: 16
Select: 0
Bây giờ, tôi đoán rằng vai 20 điểm đến từ giữa, nơi họ đang cả ràng buộc để có được xung quanh việc thực hiện tương tự. Tôi có thể thử và đăng nhập nó, nhưng nó sẽ là toàn bộ thông tin cần đưa vào. Một đồ thị sẽ tốt hơn, tôi đoán vậy.
Vì vậy, đó là những gì tôi đã làm.
Nó cho thấy rằng Select
dòng giữ ổn định (dự kiến) và Select + Where
dòng tăng lên (dự kiến). Tuy nhiên, điều khiến tôi băn khoăn là tại sao nó không đáp ứng Select
ở mức 50 hoặc sớm hơn: thực tế tôi đã mong đợi sớm hơn 50, vì một điều tra viên phụ phải được tạo ra cho Select
và Where
. Ý tôi là, điều này cho thấy sự dẫn đầu 20 điểm, nhưng nó không giải thích tại sao. Điều này, tôi đoán, là điểm chính của câu hỏi của tôi.
Tại sao nó lại hành xử như vậy? Tôi có nên tin tưởng nó? Nếu không, tôi nên sử dụng cái khác hay cái này?
Như @KingKong đã đề cập trong các bình luận, bạn cũng có thể sử dụng Sum
tình trạng quá tải mất lambda. Vì vậy, hai tùy chọn của tôi bây giờ được thay đổi thành này:
Đầu tiên:
int result = myCollection.Where(mc => mc.IsValid).Sum(mc => mc.Value);
Thứ hai:
int result = myCollection.Sum(mc => mc.IsValid ? mc.Value : 0);
Tôi sẽ làm cho nó ngắn hơn một chút, nhưng:
How much do you want to be the disambiguation percentage?
0
Starting benchmarking.
Ties: 0
Where: 60
Sum: 41
How much do you want to be the disambiguation percentage?
2
Starting benchmarking.
Ties: 8
Where: 55
Sum: 38
How much do you want to be the disambiguation percentage?
5
Starting benchmarking.
Ties: 21
Where: 49
Sum: 31
How much do you want to be the disambiguation percentage?
10
Starting benchmarking.
Ties: 39
Where: 41
Sum: 21
How much do you want to be the disambiguation percentage?
25
Starting benchmarking.
Ties: 85
Where: 16
Sum: 0
Dẫn đầu hai mươi điểm vẫn còn đó, có nghĩa là nó không liên quan đến Where
và Select
sự kết hợp được chỉ ra bởi @Marcin trong các bình luận.
Cảm ơn đã đọc qua tường văn bản của tôi! Ngoài ra, nếu bạn quan tâm, đây là phiên bản sửa đổi ghi nhật ký CSV mà Excel thực hiện.
Where
+ Select
không gây ra hai lần lặp tách biệt trên bộ sưu tập đầu vào. LINQ to Object tối ưu hóa nó thành một lần lặp. Đọc thêm về bài đăng trên blog
mc.Value
.