变量x
是带有可能值的int:-1, 0, 1, 2, 3
。
哪个表达式会更快(在CPU滴答中):
1. (x < 0)
2. (x == -1)
语言:C / C ++,但我想所有其他语言都是一样的。
P.S。我个人认为答案是(x < 0)
。
对于大师来说更广泛:如果x
从-1
到2^30
怎么办?
答案 0 :(得分:78)
这完全取决于您正在编译的ISA以及编译器优化器的质量。不要过早优化:首先查找您的瓶颈。
那就是说,在x86中,你会发现在大多数情况下两者都同样快。在这两种情况下,您都会进行比较(cmp
)和条件跳转(jCC
)指令。但是,对于(x < 0)
,可能存在某些情况,编译器可能会忽略cmp
指令,通过整个周期加速代码。
具体来说,如果值x
存储在寄存器中,并且最近是算术运算的结果(例如add
或sub
,但还有更多可能性)在EFLAGS寄存器中设置符号标志SF,则不需要cmp
指令,编译器只能发出js
指令。当输入为-1时,没有简单的jCC
指令跳转。
答案 1 :(得分:23)
为什么呢?无论您采用哪种方式,编译器都会在您当前正在编译的任何平台上对其进行优化。
如果你需要检查它是否为-1,请使用(x == -1),如果你想知道它是否小于零,请改用它。写下你会大声朗读的内容。
像这样的小事情不会让事情变得更快,你应该担心可读性和干净的设计而不是哪种微小的操作更快。即使它没有做任何逻辑更改,很可能在您的平台上,都将在一个CPU周期中执行。
答案 2 :(得分:11)
试一试,看看!做一百万甚至更好,每个十亿,并计时。我敢打赌,你的结果没有统计意义,但谁知道 - 也许在你的平台和编译器上,你可能会找到一个结果。
这是一个很好的实验,可以说服自己过早优化可能不值得你花时间 - 而且很可能是“the root of all evil--at least in programming”。
答案 3 :(得分:7)
这两个操作都可以在一个CPU步骤中完成,因此它们的性能应该相同。
答案 4 :(得分:7)
它可能取决于比较之前或之后的操作。例如,如果在进行比较之前将值赋给x,则检查符号标志可能比比较特定值更快。或者CPU的分支预测性能可能会受到您选择的比较的影响。
但是,正如其他人所说,这取决于CPU架构,内存架构,编译器以及许多其他事情,所以没有一般性的答案。
答案 5 :(得分:7)
x&lt; 0会更快。如果没有别的,它会阻止将常量-1作为操作数获取。 大多数架构都有特殊的指令用于比较零,所以这也有帮助。
答案 6 :(得分:3)
无论如何,重要的考虑因素是实际指导您的程序流程,并恰好产生相同的结果?
如果x实际上是索引或枚举中的值,那么-1将始终是您想要的,还是任何负值都有效?现在,-1是唯一的负面因素,但可能会发生变化。
答案 7 :(得分:2)
你甚至不能脱离这个问题回答这个问题。如果你尝试一个微不足道的微基准测试,那么优化器完全有可能将你的代码放到以太网中:
// Get time
int x = -1;
for (int i = 0; i < ONE_JILLION; i++) {
int dummy = (x < 0); // Poof! Dummy is ignored.
}
// Compute time difference - in the presence of good optimization
// expect this time difference to be close to useless.
答案 8 :(得分:1)
同样,这两项操作通常都是在1个时钟内完成的。
答案 9 :(得分:1)
这取决于体系结构,但x == -1更容易出错。 x&lt; 0是要走的路。
答案 10 :(得分:1)
正如其他人所说,可能没有任何区别。比较是CPU中的基本操作,芯片设计者希望尽可能快地制作它们。
但是你还可以考虑其他事情。分析每个值的频率并按顺序进行比较。这可以为您节省很多周期。当然,您仍然需要将代码编译为asm以验证这一点。
答案 11 :(得分:1)
我相信你确信这是一个真正的时间接受者。
我想要问机器会给出比我们任何人都能给出的更可靠的答案。
我发现,即使在你正在谈论的代码中,我的假设是我知道时间在哪里并不完全正确。例如,如果这是在内部循环中,如果存在任何类型的函数调用,即使是编译器插入的不可见函数调用,该调用的成本也将占据主导地位。
答案 12 :(得分:1)
尼古拉,你写道:
它实际上是瓶颈运营商 高负荷计划。表现在 这1-2个字符串更有价值 比可读性......
所有瓶颈通常都是这样 小巧,即使是完美的设计 完美的算法(虽然没有 这样)。我做高负荷DNA处理 并了解我的领域和我的算法 很好
如果是这样,为什么不做下一步:
你会得到答案。