2013-10-04 64 views
0

当使用IEEE754浮点数时,我发现了两种方法来清零32位变量的前9位。他们中的任何一个都比另一个好吗?位掩码vs移位(+ java字节码)

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 

感谢。 :)

+1

简单的整数算术运算在现代处理器上成为一个重要的性能问题是非常罕见的。有条件的分支和缓存未命中更有可能重要。 –

回答

3

Bytecode是一种可移植的中间语言。为了获得良好的性能,现代JVM将其编译为本地代码,因此不要过多地读取它:CPU实际执行的内容可能会非常不同。您将不得不分析生成的本地代码,以便能够得出关于X为什么比Y更好的结论。

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

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)

这些,当然,对于重复的数量巨大成果。

+0

我已经描述了我的代码(JProfiler),并且shinfting方法确实似乎更快(1.56x),但是我正在寻找更为一般的答案,或者至少提示我在Joni的答案中找到哪些地方。无论如何非常感谢。 :) –