1

问题 #1

在 Java 中,移动数倍比使用单个语句移动相同的数字贵吗?

例如,是

int x = 5;
x = x << 16;

比...快

int x = 5;
for (int i=0; i<16; ++i) {
    x = x << 1;
}

此外,关于

int x = 5;
for (int i=0; i<16; ++i) {
    x = x*2;
}

编辑:“x << 16”的精确性能是什么?它与“x << 1”的速度相同吗?

问题2

是否有在线资源可以用来确定 Java 中的各种按位运算性能,这样我就不必浪费 StackOverflow 用户的时间了?:-)

4

4 回答 4

5

...这样我就不必浪费 StackOverflow 用户的时间了?

你也在浪费自己的时间。编写应用程序的完整原型,对其进行分析,然后对其进行优化。我很确定您会发现瓶颈不是由于位移造成的。

这闻起来过早的优化很长一段时间。

“x << 16”的精确表现是什么?它与“x << 1”的速度相同吗?

是的,它是一样的。但从技术上讲,它实际上取决于编译器、JVM 实现、JIT、CPU 架构…… Java 规范在这种情况下对执行时间没有任何限制。

于 2012-04-25T12:25:03.330 回答
2

就基本逻辑而言,单次换档会带来更好的性能。

使用该for loop版本时,对于循环的每次迭代,都会检查循环的终止条件,i递增,执行按位运算并对 进行赋值x

使用单次移位时,将执行单次按位运算并对 进行赋值x

正如其他人所说,这确实看起来像是过早的优化。

不过,为了回答您的问题,从逻辑上讲,第一个示例比其他示例更快。

也就是说,根据语言和编译器,编译器可能会看到您for loop总是运行 16 次,然后继续优化您的代码,将其更改为x << 16. 如果是这种情况,您将看到您提供的每个代码示例之间没有区别。

于 2012-04-25T12:30:11.923 回答
1

为什么不写一个简单的基准测试并亲眼看看呢?

    long start1 = System.nanoTime();
    for (int k = 0; k < 100000000; k++) {
        int x = 5;
        x = x << 16;
    }
    long stop1 = System.nanoTime();

    long start2 = System.nanoTime();
    for (int k = 0; k < 100000000; k++) {
        int x = 5;
        for (int i = 0; i < 16; ++i) {
            x = x << 1;
        }
    }
    long stop2 = System.nanoTime();

    long start3 = System.nanoTime();
    for (int k = 0; k < 100000000; k++) {
        int x = 5;
        for (int i = 0; i < 16; ++i) {
            x = x * 2;
        }
    }
    long stop3 = System.nanoTime();

    System.out.println(stop1 - start1);
    System.out.println(stop2 - start2);
    System.out.println(stop3 - start3);
于 2012-04-25T12:31:09.220 回答
0

我会使用第一个。
但这可能几乎相同。
也许第一个更快,因为我认为 JVM 有一个内置指令,至于另一个,它必须读取几个指令,这可能会更慢。

你不应该想太多关于这些小的“速度改进”的事情。这些小算术/逻辑运算的速度是巨大的,它不会对程序性能产生太大影响。

于 2012-04-25T12:32:30.957 回答