我有一堂课,像这样:
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)。第一个应该在更多残疾人的情况下表现更好,而第二个应该在更少的情况下表现更好”。我以为他们会表现得一样好。 编辑: 然后@Martin 指出 Where 和 Select 是结合在一起的,所以实际上应该是 O (m + n)。然而,如果你看下面,似乎这是没有关系的。
(它有100多行,所以我觉得最好把它作为一个要点发布出去。)
结果... 很有趣。
天平有利于 Select
和 Where
,约30分。
您希望消除歧义的百分比是多少?
0
开始基准测试。
平局: 0
在哪里 + 选择: 65
选择: 36
这是相同的,除了一些,他们是在2% 之内。我认为这是最小误差范围。Select
和 Where
现在只领先约20个百分点。
您希望消除歧义的百分比是多少?
2
开始基准测试。
平局: 6
在哪里 + 选择: 58
选择: 37
这是我的最大误差范围。它使它有点更好的 Select
,但不多。
您希望消除歧义的百分比是多少?
5
开始基准测试。
平局: 17
在哪里 + 选择: 53
选择: 31
这超出了我的误差范围,但我仍然对结果感兴趣。因为它给了 Select
和 Where
20分的领先优势。
您希望消除歧义的百分比是多少?
10
开始基准测试。
平局: 36
在哪里 + 选择: 44
选择: 21
这是方式,方式出我的误差范围,但我仍然感兴趣的结果,因为 Select
和 Where
还是(几乎)保持他们的20点领先。它似乎在很多方面都超越了它,这就是它领先的原因。
您希望消除歧义的百分比是多少?
25
开始基准测试。
平局: 85
在哪里 + 选择: 16
选择: 0
现在,我猜测20分的领先优势来自中间,在那里他们都必须得到 在附近相同的表现。我可以试着记录下来,但是要接收的信息太多了。我觉得用图表比较好。
所以我就这么做了。
它表明,Select
线保持稳定(预期) ,而 Select + Where
线攀升(预期)。然而,让我感到困惑的是为什么它不能在50或更早的时候遇到 Select
: 事实上,我预计它会早于50,因为必须为 Select
和 Where
创建一个额外的枚举器。我的意思是,这显示了20点的领先优势,但它不能解释为什么。我想,这就是我问题的要点。
正如@KingKong 在评论中提到的,您也可以使用 Sum
的超载,它采用一个 lambda。因此,我的两个选项现在改为:
int result = myCollection.Where(mc => mc.IsValid).Sum(mc => mc.Value);
int result = myCollection.Sum(mc => mc.IsValid ? mc.Value : 0);
我会把它缩短一点,但是:
您希望消除歧义的百分比是多少?
0
开始基准测试。
平局: 0
哪里60
总和: 41
您希望消除歧义的百分比是多少?
2
开始基准测试。
平局: 8
哪里55
总和: 38
您希望消除歧义的百分比是多少?
5
开始基准测试。
平局: 21
哪里: 49
总和: 31
您希望消除歧义的百分比是多少?
10
开始基准测试。
平局: 39
哪里41号
总和: 21
您希望消除歧义的百分比是多少?
25
开始基准测试。
平局: 85
哪里16号
总和: 0
20分的领先优势依然存在,这意味着它与@Marcin 在评论中指出的 Where
和 Select
的组合无关。
谢谢你通读我的文字墙!另外,如果您感兴趣,这是是记录 Excel 接收的 CSV 的修改版本。