Java本质和性能

最初的问题是如何计算二进制数中1的个数? 我包含了使用Integer.bitCount()的性能比较,该性能可以转换为固有特性,即单个机器代码指令POPCNT和执行相同功能的Java代码。

如何计算二进制数中1的个数?
假设我有数字45,它等于二进制数101101,其中有4 1。 编写算法来执行此操作的最有效方法是什么?

回答

最好不要使用内置函数来编写算法来做到这一点。 Integer.bitCount()

使之特别有效的原因是JVM可以将其视为内在函数。 即在支持它的平台(例如,Intel / AMD)上用单个机器代码指令识别并替换整个事物
演示此优化的有效性

public static void main(String... args) {
    perfTestIntrinsic();

    perfTestACopy();
}

private static void perfTestIntrinsic() {
    long start = System.nanoTime();
    long countBits = 0;
    for (int i = 0; i < Integer.MAX_VALUE; i++)
        countBits += Integer.bitCount(i);
    long time = System.nanoTime() - start;
    System.out.printf("Intrinsic: Each bit count took %.1f ns, countBits=%d%n", (double) time / Integer.MAX_VALUE, countBits);
}

private static void perfTestACopy() {
    long start2 = System.nanoTime();
    long countBits2 = 0;
    for (int i = 0; i < Integer.MAX_VALUE; i++)
        countBits2 += myBitCount(i);
    long time2 = System.nanoTime() - start2;
    System.out.printf("Copy of same code: Each bit count took %.1f ns, countBits=%d%n", (double) time2 / Integer.MAX_VALUE, countBits2);
}

// Copied from Integer.bitCount()
public static int myBitCount(int i) {
    // HD, Figure 5-2
    i = i - ((i >>> 1) & 0x55555555);
    i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
    i = (i + (i >>> 4)) & 0x0f0f0f0f;
    i = i + (i >>> 8);
    i = i + (i >>> 16);
    return i & 0x3f;
}

版画

Intrinsic: Each bit count took 0.4 ns, countBits=33285996513
Copy of same code: Each bit count took 2.4 ns, countBits=33285996513

使用固有版本和循环的每个位数平均仅需要0.4纳秒。 使用相同代码的副本要花费6倍以上的时间(获得相同的结果)

参考: Vanilla Java博客上来自我们JCG合作伙伴 Peter Lawrey的Java Intrinsics and Performance

翻译自: https://www.javacodegeeks.com/2012/11/java-intrinsics-and-performance.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值