Ternary vs Chained If-else-if(Performance)

时间:2015-05-15 17:12:51

标签: c# performance if-statement big-o ternary

我做了尽职调查,看看以前是否曾经问过这个问题并且没有发现任何相同但接近的信息,所以这里就是这样。

假设我有一系列if-else-if语句。

foreach (value in valueList)
    if (value == 120) {
        w = true;
    } else if (value == 140) {
        x = true;
    } else if (value == 160) {
        y = true;
    } else if (value == 180) {
        z = true;
    }
}

将else-if链更改为三元表达式有什么好处,例如:

foreach (value in valueList) {
    w = (value == 120) ? true : false;
    x = (value == 140) ? true : false;
    y = (value == 160) ? true : false;
    z = (value == 180) ? true : false;
}

我的第一个倾向是否定的。由于for循环,每次循环发生时都会进行每次赋值。而在if-else-if链中,赋值只进行一次。但比较更频繁(对吧?)。任何人都可以为我解决这个问题吗?

我知道switch很容易在性能方面击败两者。我可以假设使用switch不是一个选项吗?

我想这个问题中的另一个问题是两者之间的Big-O比较是什么?

3 个答案:

答案 0 :(得分:2)

请注意,两种解决方案都非常不同。第一个只将true分配给这四个变量中的一个,而另一个将覆盖它们之前所有四个变量的值。

话虽这么说,在第二个代码中使用三元运算符真的很糟糕。您可以直接指定比较结果:

w = value == 120;
x = value == 140;
y = value == 160;
z = value == 180;

抛开语义,这也会使它比if / else结构更有效。您可能认为只运行一次比较会使其更快,因此第一个解决方案应该更好,但事实上,分支can be slow。而且由于比较操作实际上非常快,只需将比较结果分配四次就可能“更快”。

请注意,这些都不会对真正的性能产生任何影响。两者都是非常低级别的,很可能你的应用程序代码中有其他东西比较慢,是一个更有可能的瓶颈。所以我不会强调在这里使用一种或另一种方式来表现;只需选择语义正确的,然后使用任何解决方案使语义尽可能清晰。

  

我知道一个开关很容易在性能方面击败两者。

switch语句给你的效果与ifs和elses链相同,所以这里没有什么区别。

  

我想这个问题中的另一个问题是两者之间的Big-O比较是什么?

两者都是线性的,因为你只是在列表中循环。其他每个差异都是不变的,因此在Big-O表示法中无关紧要。

答案 1 :(得分:1)

两个功能完全不同。表现无关紧要;他们不做同样的事情。

如果符合条件,第一个代码段会将相应的变量设置为true,如果不满足相应条件则不执行任何操作,这意味着它保留原始值。

第二个片段在每次迭代时为每个变量分配一个值。

所以第一个片段实际上是在询问,"是等于这个数字的任何值"对于每个数字,第二个片段实际上是在询问,"是最后一个等于这个数字的值"对于每个数字。我假设您打算使用前者,而不是后者,所以后者只是错误

答案 2 :(得分:0)

嗯,在integers的情况下,当我的案例太多时,我真的很想使用switch。 @ima在this回答中解释了这一点。否则,只有看起来更好或更好的东西才会更重要"可读"

然而,如this帖子中所述,使用switchstrings完全不同。