У меня есть класс, например:
public class MyClass
{
public int Value { get; set; }
public bool IsValid { get; set; }
}
На самом деле он намного больше, но это воссоздает проблему (странность).
Я хочу получить сумму Value
, где экземпляр действителен. До сих пор я нашел два решения.
Первый из них:
int result = myCollection.Where(mc => mc.IsValid).Select(mc => mc.Value).Sum();
Вторым, однако, является следующее:
int result = myCollection.Select(mc => mc.IsValid ? mc.Value : 0).Sum();
Я хочу получить наиболее эффективный метод. Сначала я думал, что второй будет более эффективным. Тогда теоретическая часть меня начала идти "Ну, один из них O (n + m + m), другой - O (n + n). Первый должен работать лучше с большим количеством инвалидов, а второй должен работать лучше менее". Я думал, что они будут действовать одинаково. EDIT: И тогда @Martin указал, что Where и Select были объединены, поэтому на самом деле это должно быть O (m + n). Однако, если вы посмотрите ниже, похоже, что это не связано.
Итак, я положил его на тест.
(Это 100 + строк, поэтому я подумал, что лучше разместить его как Gist.)
Результаты были... интересными.
С допуском 0%:
Шкалы в пользу Select
и Where
, примерно на ~ 30 пунктов.
How much do you want to be the disambiguation percentage?
0
Starting benchmarking.
Ties: 0
Where + Select: 65
Select: 36
С допуском на 2%:
То же самое, за исключением того, что для некоторых они были в пределах 2%. Я бы сказал, что минимальная погрешность. Select
и Where
теперь имеют всего лишь 20-точечное лидерство.
How much do you want to be the disambiguation percentage?
2
Starting benchmarking.
Ties: 6
Where + Select: 58
Select: 37
С допуском 5% привязки:
Я бы сказал, что это мой максимальный запас ошибки. Это немного лучше для Select
, но не так много.
How much do you want to be the disambiguation percentage?
5
Starting benchmarking.
Ties: 17
Where + Select: 53
Select: 31
При разрешении 10%:
Это выход из моей погрешности, но меня все еще интересует результат. Потому что он дает Select
и Where
двадцатиточечное лидерство, которое у него было какое-то время.
How much do you want to be the disambiguation percentage?
10
Starting benchmarking.
Ties: 36
Where + Select: 44
Select: 21
С допуском 25% привязки:
Это путь, способ из моего поля ошибки, но меня все еще интересует результат, потому что Select
и Where
еще ( почти) держат свои 20 очков. Кажется, что он превосходит его в нескольких немногих и что дает ему преимущество.
How much do you want to be the disambiguation percentage?
25
Starting benchmarking.
Ties: 85
Where + Select: 16
Select: 0
Теперь, я предполагаю, что 20-точечное лидерство появилось из середины, где оба должны были получить вокруг ту же производительность. Я мог бы попытаться зарегистрировать его, но это будет целая нагрузка информации. Граф будет лучше, я думаю.
Итак, что я сделал.
Это показывает, что строка Select
остается устойчивой (ожидаемой) и что линия Select + Where
поднимается (ожидается). Однако, что меня озадачивает, это то, почему он не соответствует Select
в 50 или более ранних версиях: на самом деле я ожидал раньше 50, поскольку дополнительный счетчик должен был быть создан для Select
и Where
. Я имею в виду, что это показывает лидерство в 20 пунктов, но это не объясняет почему. Это, я думаю, является основным моментом моего вопроса.
Почему он ведет себя так? Должен ли я доверять этому? Если нет, следует ли использовать другой или этот?
Как упоминается в комментариях @KingKong, вы также можете использовать перегрузку Sum
, которая принимает лямбда. Итак, мои два варианта теперь изменены на:
Во-первых:
int result = myCollection.Where(mc => mc.IsValid).Sum(mc => mc.Value);
Во-вторых:
int result = myCollection.Sum(mc => mc.IsValid ? mc.Value : 0);
Я собираюсь сделать это немного короче, но:
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
Двадцатиточечное лидерство все еще существует, что означает, что это не связано с комбинацией Where
и Select
, отмеченной @Marcin в комментариях.
Спасибо, что прочитали мою стену текста! Кроме того, если вам интересно, здесь измененная версия, которая регистрирует CSV, который принимает Excel.