这些代码之间有区别吗

Is there a difference between these codes

本文关键字:有区别 之间 代码      更新时间:2023-10-16

我今天在编写代码时,遇到了一些我一直在做的事情,我想知道它是否有后遗症。

有两种做同样事情的方法

if(foo != true)
{
bar ++;
}
if(foo == true)
{
}
else
{
bar ++;
}

现在我知道编译器可能会优化这一点,但我想知道区别,因为你不能总是指望它们。

我的问题是,第二个选项真的会因为在检查中添加了另一个命令而受到某种惩罚吗?

是的,这是一个打字错误。

两者都不好。除了第二个包含拼写错误(=而不是==)之外,将布尔值与常量进行比较是多余的。直接测试它们的价值:

if (! foo) …
// Instead of
if (foo != true) …
// or
if (foo) …
// Instead of
if (foo == true) …

首先,它消除了通过打字错误创建错误的可能性(正如您所展示的)。但除此之外,这更符合逻辑。

(但请注意,它不是更高效。语句是严格等效的。)

任何优秀的编译器都可能发出相同的效果和机器代码-检查布尔值并选择要做的操作将以最快的方式完成。"添加else"并不是它内部的工作方式——这只是if-else语句必须具有一定的效果,如何实现这种效果取决于编译器。仅仅添加一个关键字并不一定会导致额外的代码排放。

如果你真的很关心,你应该检查发出的机器代码,看看编译器在每种情况下发出了什么。

我想你在写=而不是==时错别字了。这些块并不等价:现代CPU试图在程序运行时预取和预执行汇编指令,当满足条件跳转时,CPU预运行条件为真时将执行的代码。

因此,我通常会将可能更频繁执行的代码放在首位,尽管编译器所做的分支预测和其他优化可能会改变这一点,并做得更好。

编辑:请看一下维基百科上的分支预测,尤其是静态预测部分。除非你100%确定编译器会做什么优化,以及CPU会运行你的代码,否则你最好假设第一个块运行得更快。在最坏的情况下,你没有得到任何好处,也没有损失。在最好的情况下,您正在制作更易于阅读和运行速度更快的代码。

反例:

if (someCondition)
    AssertNotReached();
else
    DoRealWork();

两者不相同,在第二个代码中,if语句总是以给定的foo=true执行。

有一个很大的区别,第一个inc的bar基于一个条件,第二个inc将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 ++;
}

假设上面是一个拼写错误,它们在机器级别上是相同的,但在解析时间和写出所需的时间方面是不同的。

这取决于编译器。在更糟糕的情况下,它会添加几个额外的跳转指令。

语义这是一样的。除此之外会发生什么取决于编译器通常,使用if语句,编译器会假设"if"分支更有可能被采用,并为此进行优化。如果发生这种情况,第二个示例确实会有一些性能损失。但这实际上取决于我们从问题的背景中不知道的许多事情。