位屏蔽与移位(+ java字节码)

时间:2013-10-04 23:24:28

标签: java bit-manipulation bytecode bit-shift bitmask

当使用IEEE754浮点数时,我发现了两种方法可以将32位变量的前9位置零。他们中的任何一个比另一个好吗?

Java相关补充:是否有一些列表提供有关指令效率的信息?我随机发现BIPUSH通常比LDC更快,但其他任何东西都没有。

// 10111111110010100011110101110001 bits
// 00000000010010100011110101110001 significand

int bits = 0b10111111110010100011110101110001;
int significand = bits & 0b11111111111111111111111;
int significand2 = bits << 9 >>> 9;

...字节码

L4
    LINENUMBER 49 L4
    ILOAD 0
    LDC 8388607 // = 0b11111111111111111111111
    IAND
    ISTORE 5
L5
    LINENUMBER 50 L5
    ILOAD 0
    BIPUSH 9
    ISHL
    BIPUSH 9
    IUSHR
    ISTORE 6

感谢。 :)

2 个答案:

答案 0 :(得分:3)

字节码是一种可移植的中间语言。为了获得不错的性能,现代JVM将其及时编译为本机代码,因此不要过多地阅读它:CPU实际执行的内容可能看起来非常不同。您必须分析生成的本机代码才能得出X为什么比Y表现更好的结论。

如何打印生成的汇编程序代码取决于JVM,请参阅此处获取Hotspot(即Oracle JDK和OpenJDK)的说明:http://mechanical-sympathy.blogspot.com/2013/06/printing-generated-assembly-code-from.html

答案 1 :(得分:0)

一般来说,换班操作应该更快。这是一个简单的Java测试和结果值:

int bits = 0b10111111110010100011110101110001;

long time = System.nanoTime();
int significand;
for (int i = 0; i < 1000000000; i++) {
    significand = bits & 0b11111111111111111111111;
}
System.out.println(String.format("Time: %f (ms)",
    (System.nanoTime() - time) / 1000000f));

long time2 = System.nanoTime();
for (int i = 0; i < 1000000000; i++) {
    significand = bits << 9 >>> 9;
}
System.out.println(String.format("Time 2: %f (ms)",
    (System.nanoTime() - time2) / 1000000f));

时间1:7.003190(ms)
时间2:2.633435(ms)

这些当然会导致大量的重复。