这取决于很多因素,但主要取决于您告诉编译器要优化的内容(如果有的话)。
如果编译器设置为优化大小(最小字节码),那么有时它会使用XOR
在看似奇怪的地方。例如,X86使用的可变长度编码方案可以设置一个寄存器来0 by XOR
'ing 本身的代码字节数比使用所需的代码少MOV
操作说明。
考虑使用的代码XOR
:
if ( (val ^ ~0U) == 0 ) /* 3-bytes to negate and test (x86) */
XOR eax,0FFFFFFFFh
需要 3 个字节AND设置/清除零标志 (ZF)
现在,考虑使用的代码NOT
:
if ( (~val) == 0) /* 4-bytes to negate and test (x86) */
NOT eax
被编码成2字节指令,但不影响CPU标志。
TEST eax,eax
添加额外的 2 个字节,并且需要设置/清除零标志 (ZF)
NOT
也是一个简单的指令,但由于它不影响任何CPU标志,因此您必须发出TEST
之后指示使用它进行分支,如代码中所示。这实际上会产生更大的字节码,因此设置为优化大小的智能编译器将probably尽量避免使用NOT
。这两条指令一起完成所需的周期数因 CPU 代的不同而异,并且当智能编译器被告知优化速度时,也会将其纳入其决策中。
If you are not writing hand-tuned assembly, it is best to use whatever is clearest to a human and hope that the compiler is smart enough to choose different instructions/scheduling/etc. to optimize for size/speed as requested at compile-time. Compilers have a smart set of heuristics they use to choose and schedule instructions, they know more about the target CPU architecture than the average coder.
如果您后来发现这个分支确实是一个瓶颈,并且没有更高级别的方法来解决该问题,那么您可以进行一些低级别的调整。然而,如今,除非您的目标是低功耗嵌入式 CPU 或内存有限的设备,否则这是一件微不足道的事情。我通过手动调整来挤出足够的性能以使其值得的唯一地方是受益于数据并行性的算法,并且编译器不够智能,无法有效地利用 MMX/SSE 等专用指令集。