三元运算符?:vs if ... else

时间:2010-08-25 11:34:13

标签: c++ performance conditional-operator

在C ++中,?:运算符比if()... else语句更快?它们在编译代码中有什么区别吗?

14 个答案:

答案 0 :(得分:93)

它并不快。根据某个表达式初始化常量变量有一个区别:

const int x = (a<b) ? b : a;

您不能对if-else执行相同操作。

答案 1 :(得分:82)

取决于您的编译器,但在任何现代编译器上通常没有区别。这是你不应该担心的事情。专注于代码的可维护性。

答案 2 :(得分:40)

我已经看到GCC将条件运算符转换为cmov(条件移动)指令,同时将if语句转换为分支,这意味着在我们的情况下,使用条件运算符时代码更快。但那是几年前,而且很可能在今天,两者都会编译成相同的代码。

无法保证他们将编译为相同的代码。如果您需要性能,那么一如既往, measure 。当你测量并发现1.你的代码太慢,并且2.这是特定的代码块是罪魁祸首,然后研究编译器生成的汇编代码并自己检查发生了什么。

不要相信黄金规则,“如果我使用条件运算符,编译器将始终生成更高效的代码”。

答案 3 :(得分:14)

它们是相同的,但是,三元运算符可以在难以使用if / else的地方使用:

printf("Total: %d item%s", cnt, cnt != 1 ? "s" : "");

使用if / else执行该语句将生成一个非常不同的编译代码。


8年后更新......

实际上,我认为这会更好:

printf(cnt == 1 ? "Total: %d item" : "Total: %d items", cnt);

(实际上,我很确定你可以用“one”替换第一个字符串中的“%d”)

答案 4 :(得分:2)

只是有点左撇子......

x ? y : x = value
如果 x 不为0(false),

会将分配给 y

答案 5 :(得分:2)

无论编译代码如何,它们在语义上都是不同的东西。 <cond>?<true expr>:<false expr>是一个表达式,if..else..是一个声明。

虽然条件表达式的语法看起来很尴尬,但它是一件好事。您被迫提供<false expr>,并且两个表达式都经过类型检查。

在基于表达式的函数式语言(如Lisp,Haskell)中等效于if..else..在C ++中为? :,而不是if..else..语句。

答案 6 :(得分:0)

现在我无法帮助你,我可以帮助解决它下面的第二个问题,我想用它吗?如果您只想知道速度,请忽略我的评论。

我所能说的是,请在使用三元时非常聪明? :运营商。对于可读性而言,这可能是一种祝福,也可能是一种诅咒。

问问自己在使用之前是否更容易阅读

int x = x == 1 ? x = 1 : x = 1;

if (x == 1)
{
   x = 1
}
else
{
   x = 2
}

if (x == 1)
    x = 1
else
    x = 1

是的,使代码100%伪造看起来很愚蠢。但是这个小技巧帮助我分析了代码的可读性。这是您在此示例中看到的运算符的可读性,而不是内容。

它看起来很干净,但平均马桶座和门把手也是如此。

根据我的经验,这是有限的,我看到很少有人真正能够快速引渡三元运营商所需的信息,除非100%确定它更好。当我想到它时,修复它是一种痛苦

答案 7 :(得分:0)

我希望在大多数编译器和目标平台上,都会出现“if”更快的情况以及?:更快的情况。还有一种形式或多或少紧凑的情况。哪种情况支持一种形式或另一种形式在编译器和平台之间会有所不同。如果您在嵌入式微型计算机上编写性能关键代码,请查看编译器在每种情况下生成的内容,并查看哪个更好。在“主流”PC上,由于缓存问题,唯一可以看出哪种更好的方法是将这两种形式基于真实应用程序。

答案 8 :(得分:0)

在倒转一些代码(几年前我不记得)时,我看到机器代码之间的单行差异:?如果 - 否则。 Don't remember much but it is clear that implementation of both is different.

但我建议你不要选择其中一个b'coz的效率,根据代码的可读性或你的方便选择。 快乐编码

答案 9 :(得分:0)

三元运算符始终返回一个值。 因此,在您想要从结果中获得某些输出值的情况下,使用三元运算符总是只有2个条件总是更好。 如果上述任何条件不成立,请使用if-else。

答案 10 :(得分:0)

我认为在某些情况下,内联if可以产生“更快”的代码,因为它的工作范围。对象创建和销毁可能代价高昂,因此请考虑以下方案:

class A{
    public:
    A() : value(0) {
        cout << "Default ctor" << endl;
    }
    A(int myInt) : value(myInt)
    {
        cout << "Overloaded ctor" << endl;
    }

    A& operator=(const A& other){
        cout << "= operator" << endl;
        value = other.value; 
    }

    ~A(){
        cout << "destroyed" << std::endl;
    }

    int value;

};


int main()
{
   {
       A a;
       if(true){
           a = A(5);
       }else{
           a = A(10);
       }
   }

   cout << "Next test" << endl;
   {
        A b = true? A(5) : A(10);
   }
   return 0;
}

使用此代码,输出将为:

Default ctor                                                                                                                                                                                                                      
Overloaded ctor                                                                                                                                                                                                                   
= operator                                                                                                                                                                                                                        
destroyed                                                                                                                                                                                                                         
destroyed                                                                                                                                                                                                                         
Next test                                                                                                                                                                                                                         
Overloaded ctor                                                                                                                                                                                                                   
destroyed  

因此,通过内联if,我们保存了一些操作,以使a在与b相同的范围内保持活动状态。虽然条件评估速度很可能在两种情况下都非常相等,但更改范围会强制您考虑其他因素,即内联如果允许您避免。

答案 11 :(得分:0)

您不必将其全部放在一行: -

x = y==1 ?
    2
    :// else
    3;

它比if / else更清晰,因为你可以立即看到两个分支导致x被分配。

答案 12 :(得分:-1)

在C中,三元运算符“?:”可用于构造形式

的条件表达式
exp1 ? exp2:exp3

其中exp1,exp2和exp3是表达式

例如

        a=20;
        b=25;
        x=(a>b)?a:b;

        in the above example x value will be assigned to b;

可以使用 if..else 语句编写,如下所示

            if (a>b)
             x=a;
             else
             x=b;

**因此这两者之间没有区别。这对于程序员来说很容易编写,但对于编译器来说都是一样的。*

答案 13 :(得分:-4)

不,它们被转换为完全相同的可执行代码。