今天,当我偶然发现我做的事情时,我没有想到是否有任何后续影响。
以下是两种做同样事情的方法
if(foo != true)
{
bar ++;
}
if(foo == true)
{
}
else
{
bar ++;
}
现在我知道编译器可能会对此进行优化,但我想知道它们之间的区别,因为你不能总是指望它们。
我的问题是第二种选择是否真的会引起某种惩罚,因为它会给支票添加另一个命令?
是的,这是一个错字。
答案 0 :(得分:10)
两者都不好。除了第二个包含拼写错误(=
而不是==
)之外,将布尔值与常量进行比较只是多余的。只是直接测试他们的价值观:
if (! foo) …
// Instead of
if (foo != true) …
// or
if (foo) …
// Instead of
if (foo == true) …
首先,它消除了通过拼写错误创建错误的可能性(正如您已经慷慨地展示的那样)。但除此之外,它更合乎逻辑。
(但请注意,不更有效。声明严格相同。)
答案 1 :(得分:5)
那些具有相同的效果,并且任何体面的编译器都可能发出相同的机器代码 - 检查布尔值并选择做什么将以尽可能最快的方式完成。 “添加else
”并不是它在内部的工作原理 - 这只是必须具有一定效果的if-else
语句,由编译器决定如何实现这种效果。只添加一个关键字并不一定会导致额外的代码发射。
如果您真的在意,您应该检查发出的机器代码并查看编译器在每种情况下发出的内容。
答案 2 :(得分:3)
我认为你写了一个拼写错误=而不是==。这些块不等同:现代CPU在程序运行时尝试预取和预执行汇编指令,当满足条件跳转时,CPU预先运行条件为真时执行的代码。
所以我通常把可能更频繁执行的代码置于最顶层,尽管编译器做的分支预测和其他优化可能会改变这一点并做得更好。
编辑:请查看维基百科上的Branch prediction,尤其是静态预测部分。除非您确定100%的编译器将执行哪些优化以及CPU将运行您的代码,否则最好的选择是假设第一个块运行得更快。在最坏的情况下,你没有任何好处,也没有损失。在最好的情况下,您创建的代码更易于阅读并且运行得更快。
反示例:
if (someCondition)
AssertNotReached();
else
DoRealWork();
答案 3 :(得分:2)
两者都不相同,在你的第二个代码中,if语句总是以foo = true的形式执行。
答案 4 :(得分:1)
存在很大差异,第一个inc bar
基于条件,第二个将foo
设置为true。
if(foo != true)
{
bar ++;
}
if(foo = true) //this sets foo to true and takes the true branch of the statement, any optmizing compiler will remove the else section
{
}
else
{
bar ++;
}
假设以上是拼写错误,它们在机器级别上是相同的,但它们在分析时间和写出时间方面是不同的。
答案 5 :(得分:0)
这取决于编译器。在更糟糕的情况下,它会添加一些额外的跳转指令。
答案 6 :(得分:0)
语义上这是一样的。除此之外会发生什么取决于编译器。 通常,使用if语句,编译器将假定更有可能采用“if”分支并对此进行优化。如果发生这种情况,第二个例子确实会有一些性能损失。但这实际上取决于我们从问题的背景中不知道的许多事情。