我在相当数量的Java代码中看到过这样的东西:
int blah = ~someFunc() + 1;
而不是
int blah = -1 * someFunc();
这里的输出有什么真正的区别吗? javac是否认识到这两种情况之间的区别?似乎编译器应该能够将这两行转换为相同的字节代码。
编辑:这不是关于 位如何翻转的问题,而是一个关于为什么实施者可能会选择某种操作方法的问题。
Edit2:我在一个简单的测试中做了javap -c,这里有一些JVM字节码:
int one = -1 * someFunc();
0: iconst_m1
1: invokestatic #2 // Method someFunc:()I
4: imul
5: istore_1
int two = ~someFunc() + 1;
6: invokestatic #2 // Method someFunc:()I
9: iconst_m1
10: ixor
11: iconst_1
12: iadd
13: istore_2
因此,还有3个用于位翻转的java指令(即iconst_m1, ixor
)加1,但是如何转换为机器周期可能是特定于体系结构的。
答案 0 :(得分:1)
严格说明指令成本,第一种方法确实可以更快(在某些处理器上): 例如,访问 http://www.agner.org/optimize/instruction_tables.pdf并比较运营成本:
IMUL r32 = 3 ops
ADD = 1 op
NOT = 1 op
因此,您可以保存一个操作。另一方面,每个函数调用都要求你将vars放在寄存器堆栈上并从中检索它们,这会增加额外的成本。