在Java中,按位操作比模数/提醒操作符更快吗?

Nir*_*jan 5 java bit-manipulation

我在几个博客中读到,在Java模数/提醒操作符中比按位-EN慢.所以,我编写了以下程序进行测试.

public class ModuloTest {
    public static void main(String[] args) {
        final int size = 1024;
        int index = 0;

        long start = System.nanoTime();
        for(int i = 0; i < Integer.MAX_VALUE; i++) {
            getNextIndex(size, i);
        }
        long end = System.nanoTime();
        System.out.println("Time taken by Modulo (%) operator --> " + (end - start) + "ns.");

        start = System.nanoTime();
        final int shiftFactor = size - 1;
        for(int i = 0; i < Integer.MAX_VALUE; i++) {
            getNextIndexBitwise(shiftFactor, i);
        }
        end = System.nanoTime();
        System.out.println("Time taken by bitwise AND --> " + (end - start) + "ns.");
    }

    private static int getNextIndex(int size, int nextInt) {
        return nextInt % size;
    }

    private static int getNextIndexBitwise(int size, int nextInt) {
        return nextInt & size;
    }
}
Run Code Online (Sandbox Code Playgroud)

但在我的运行时环境(MacBook Pro 2.9GHz i7,8GB RAM,JDK 1.7.0_51)中,我看到了其他情况.按位-AND显着较慢,实际上比其余运算符慢两倍.

如果有人能帮助我理解这是预期的行为还是我做错了什么,我将不胜感激?

谢谢,Niranjan

dha*_*ram 1

特别是这个例子总是会给你一个错误的结果。此外,我相信任何计算 2 的幂模的程序都会比按位 AND 更快。

原因:当您使用 N % X(其中 X 是 2 的 k 次方)时,仅考虑最后 k 位进行取模,而在按位 AND 运算符的情况下,运行时实际上必须访问所讨论数字的每一位。

另外,我想指出 Hot Spot JVM 优化了类似性质的重复计算(示例之一可以是分支预测等)。在您的例子中,使用模数的方法仅返回数字的最后 10 位,因为 1024 是 2 的 10 次方。

尝试使用一些素数值作为大小并检查相同的结果。

免责声明:微观基准测试并不被认为是好的。