这些代码之间有区别吗
Is there a difference between these codes
我今天在编写代码时,遇到了一些我一直在做的事情,我想知道它是否有后遗症。
有两种做同样事情的方法
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"分支更有可能被采用,并为此进行优化。如果发生这种情况,第二个示例确实会有一些性能损失。但这实际上取决于我们从问题的背景中不知道的许多事情。
- 在 typedef 内部使用 const 关键字和在 typedef 外部使用 const 关键字之间有区别吗?
- static_cast<unsigned>(签名)与标准::bit_cast<unsigned>(签名)之间有区别吗?
- 在调用函数时,ptr** 和 ptr*& 之间是否有区别,或者首选C++?
- 为什么 .cpp 文件和 .h 文件之间有区别?
- C++:调用运算符和调用其实现之间有区别吗
- 将全局声明为类声明语句的一部分与使用单独的语句声明全局之间是否有区别
- 用户定义的类和标准类之间有区别吗?
- 这两个数组之间有区别吗?
- 这些在C 中初始化C数组的方式之间有区别吗?
- vector.size()= 0和vector.empty()之间是否有区别
- 显式运算符 = 调用和 = 运算符之间是否有区别
- 这两种初始化成员变量的方法之间有区别吗?
- 在DirectX中,深度值中存储了哪些值?这在DX9和DX11之间有区别吗
- 如果"foo"是引用变量,[&foo]{ ... } 捕获和 [foo]{ ... } 捕获之间有区别吗?
- 在进行正向声明时,不命名参数和命名参数之间有区别吗
- 这两个fors之间有区别
- C++ 中的以下类似语句之间有区别吗?
- int x{} 之间有区别吗?和整数 x = 0;
- 具有公共成员而没有构造函数的结构和类之间的编译器是否有区别
- 在分配器中使用new函数和*alloc函数时,它们之间有区别吗