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