在C++中,是吗?:运算符比if()更快。…else语句?它们在编译代码中有什么区别吗?
- 困难的问题,因为它还取决于编译器的优化设置。
- 这当然取决于你在树枝里做什么。条件运算符只允许表达式,而if允许语句。
- 相关:三元还是三元?
- 有人随机决定编辑我的三年前的问题,重写这个问题,让它听起来完全不同于我,并添加一些完全不必要的代码,使整个问题毫无意义,因为由于不断折叠,这两个样本都简化为简单的"result=5"。回复。
- 程序集版本cmov vs jmp stackoverflow.com/questions/14131096/…
它不快。当您可以根据某个表达式初始化常量变量时,有一个区别:
1
| const int x = (a<b) ? b : a; |
你不能对if-else做同样的事情。
- 是的,使用"if else"首先初始化一些默认值,然后分配一个新值。花费了更多的处理器周期。
- @开发者艺术:使用const变量是不可能的。
- 您可以创建一个非常量变量,在if/else中分配给它,然后创建一个新的常量变量,并用非常量构造它。相当浪费,但并非不可能。
- @Deadmg,最后,您将在同一范围内得到另一个变量,这将使
could这不一样。
- 我说这是浪费。你只举了一个例子来说明它是一种浪费。但这绝对不是不可能的。
- 初始化常量成员时如何?
- 很好,兰伯特会"解决"这个,如果/否则:)哈哈
- @deadmg:不能用if/else编写整型常量表达式,但可以用?:编写整型常量表达式。这才是真正的区别。实用:不能用if/else重写char foo[ a < b ? b : a ];;声明将以错误的范围结束。
- 也不能用它来书写吗?:,因为[]不仅需要是const,还需要constexpr,其结果是什么?:除非A和B都是constexpr,否则不是吗?:不会编译为任何机器代码。编辑:还有alloca,它的参数是runtime。
- 那好的ol'max呢?const int x = max(a,b);工作得很好。
- @波波波波哈!当我读到你的评论时,我认为你所建议的命令是以东(6),我想哇!WTF就是这样!然后我又看了一遍,发现问号不是单空格!考虑到这个话题,我认为我有理由这么想?是指挥部的一部分!:)
取决于您的编译器,但对于任何现代编译器,通常都没有区别。这是你不应该担心的事情。专注于代码的可维护性。
- +1对于许多应用程序,即使在真正的转储编译器上,性能差异也不值得考虑。
- 关于代码的可维护性,我更希望……否则。至少对我来说,它更容易阅读。
- @Exa:取决于上下文。初始化对象时,三元运算符通常更好。
- @这就是为什么我说"至少对我来说"。我只是指代码的可读性:)
- 我可以问一下,一个条件如何比一个"如果"更不可维护?如果你有两个相同的选择,坚持选择较慢的是过早的纠缠。
- @Kotlinski,我并不是说条件比if更难维护。它们在特定的、不同的情况下都更清楚,如上文所述的对三元或不对三元问题的回答。
- 我遇到了一个交叉的例子,在这个例子中,三元选择阻止了移动结构的使用,与if/else相比产生了额外的副本。
- 已经很老了。然而,我读了这个答案,我不明白为什么三元之间有区别,如果不是,当它来推断返回类型(见"返回类型"一节)。我想问一个问题,但后来我找到了这个问题,现在我对答案有点不满意;)
我见过gcc将条件运算符转换成EDOCX1(条件移动)指令,而将if语句转换成分支,这意味着在我们的例子中,使用条件运算符时代码更快。但那是几年前的事了,而且很可能是今天,两者都会编译成相同的代码。
不能保证它们会编译成相同的代码。如果您需要性能,那么一如既往地测量。当你测量并发现1.你的代码太慢了,2。正是这段特定的代码才是罪魁祸首,然后研究编译器生成的汇编代码,并自己检查发生了什么。
不要相信"如果我使用条件运算符,编译器总是会生成更高效的代码"这样的黄金法则。
- + 1。当我使用gcc为ps3开发时,使用条件而不是"if"可以避免分支。
- 这是C语言的特异性?《标准C++ Only one of the second and third expressions is evaluated. Every value computation and side effect associated with the first expression is sequenced before every value computation and side effect associated with the second or third expression.which of the apparently说,防止在从教学cmove编译器生成。
- zoujyjs @ C has the same不规则。但在AS—if the is free to the rule,编译器的欺骗,只要最后的结果是正确的。我知道只要there are the端不影响,这可以让编译器优化。
- 如何实施"订单cmov if和else?在移动cmov to to value值2 1 +?
- 注:this is outdated(CIRA)2010年的建议,我不reproduce this在线顾客4.4或以后。
但是,它们是相同的,三元运算符可用于难以使用if/else的位置:
1
| printf("Total: %d item%s", cnt, cnt != 1 ?"s" :""); |
使用if/else执行该语句将生成一个非常不同的编译代码。
8年后更新…
实际上,我认为这样做会更好:
1
| printf(cnt == 1 ?"Total: %d item" :"Total: %d items", cnt); |
(实际上,我很确定您可以将第一个字符串中的"%d"替换为"one")。
- 甚至不需要三元运算符:printf("Total: %d item%s", cnt,"s" + (cnt==1));。
- @msalters但是在字符串的末尾给出了一个双null,这在其他情况下可能是一个问题,在这种情况下,双null意味着某种东西(例如在lpStrFilteropenfilename结构的成员中)。
- @bobobobo:no.%s从源字符串打印到但不包括\0。
- 哦,是的,你说得对。甜的。
- @msalters这个printf("Total: %d item%s", cnt,"s" + (cnt==1));是如何工作的?
- @怪癖:(cnt==1)是真是假,它转换为0或1。s"是指向以nul结尾的字符串的指针。添加一个跳过一个字符。所以这张照片要么是"S",要么是。
不管编译的代码是什么,它们在语义上都是不同的。?:是一个表达式,if..else..是一个语句。
虽然条件表达式的语法看起来很笨拙,但它是一件好事。您必须提供一个,这两个表达式都经过类型检查。
在基于表达式的函数语言(如Lisp,Haskell)中,EDCOX1等于3是EDCOX1(6)在C++中,而不是EDCOX1×3的语句。
只是有点左撇子…
如果x不是0(假),则将为y赋值。
- 你确定吗?……
- 问题:stackoverflow.com not without性括号/ / / 7499400 & hellip;
- 错误(EEA stackoverflow.com 7499505 2436175 / / /)。besides has it to do with,是什么问题?
你不必把这些都放在同一行上:
1 2 3 4
| x = y==1 ?
2
:// else
3; |
它比if/else更清晰,因为您可以立即看到两个分支都导致x被分配给。
我认为在某些情况下,由于内联if的工作范围,它可以生成"更快"的代码。对象创建和销毁成本高昂,因此请考虑以下场景:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| 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;
} |
使用此代码,输出将是:
1 2 3 4 5 6 7 8
| Default ctor
Overloaded ctor
= operator
destroyed
destroyed
Next test
Overloaded ctor
destroyed |
因此,通过引入if,我们节省了一系列操作,以使a在与b相同的范围内保持活动。虽然在这两个场景中,条件评估速度很可能是相等的,但是更改范围会迫使您考虑内联if允许您避免的其他因素。
- 和我A a(true ? 5 : 10);about
三元运算符始终返回值。所以,在您希望从结果中得到一些输出值的情况下,只有两个条件总是更好地使用三元运算符。如果上述任何条件不正确,请使用if else。
在逆转某些代码的过程中(几年前我不记得了),我看到了机器代码之间的单行差异:?如果有的话。Don't remember much but it is clear that implementation of both is different.
但我建议您不要选择其中一个,因为它的效率,根据代码的可读性或您的方便选择。快乐编码
- 差分是one of them the other for using语句是使用分支和saome是原生指令,我不记得是哪一个用which。
我希望在大多数编译器和目标平台上,"if"更快,而"cases"在哪里?更快。还有一些情况下,一种形式或多或少比另一种形式紧凑。哪种情况有利于一种形式,或者另一种形式在编译器和平台之间会有所不同。如果您在嵌入式micro上编写性能关键的代码,请查看编译器在每种情况下生成的代码,并查看哪种代码更好。在"主流"PC上,由于缓存问题,唯一更好的方法是用类似于真实应用程序的东西对两个表单进行基准测试。
现在我帮不了你了,我也许能帮你解决下面的第二个问题,我想用它吗?如果你只是想知道速度,忽略我的评论。
我能说的是,请你对什么时候使用三元非常聪明?接线员。它既是对可读性的诅咒,也是一种祝福。
在使用前问问自己是否觉得这个更容易阅读
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| 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%确定这更好。我想,当它被窃听的时候,修复它是一种痛苦
- 第一int x = x == 1 ? 1 : 2or should probably在线读possibly int x = (x == 1) ? 1 : 2
- 给我点merely was the view of the Code of one,is the cleanlyness在线是好的。但如果你想看到assignement the content of the condition/can be bogus队列。如果你想什么你看什么是广告经营者and the location at the光环。看到if the word &()知道,啊,that is a condition。把a = b?你immedeatly condition:condition that for yourself现货?我知道大多数人计划Do not,也许是因为大多数人,我知道我是rookies程序类。你是在正确的ofc the numbers是废话,那点茶。
- 当然parentheses needs some第一行。也许"int x=(Y==1)?0"或"1;:((int x=y==1)?1 0:");
- 我很抱歉,但我没有看到the指派问题。如果你overcomplicate choose to the example to make your点,那是你的问题。你为什么不写x = x = 1;到处和我complain that is and should be指派avoided太复杂。
三元运算符"?:"可用于构造窗体的条件表达式
其中exp1、exp2和exp3是表达式
例如
1 2 3 4 5
| a=20;
b=25;
x=(a>b)?a:b;
in the above example x value will be assigned to b; |
这可以使用if..else语句编写,如下所示
1 2 3 4
| if (a>b)
x=a;
else
x=b; |
**因此这两者没有区别。这对于程序员来说很容易编写,但是对于编译器来说两者都是相同的。*
不,它们被转换为完全相同的可执行代码。
- -1:在什么版本的编译器上,在什么平台上,用什么代码?
- Deadmg:vb6编译器,显然!