为什么java中的lib func比自定义运行得更快?

kid*_*idd 2 java

我最近对 ​​Integer.bitCount 做了一些调查。我发现一个有趣的结果是 Integer.bitCount 比我自己的 func 快得多,即使代码是相同的。

我以为是JIT造成的,但是查了一下文档,发现JIT是基于运行时策略的。这让我很困惑。

public static void main(String[] args) {
    long sum = 0;
    long start, end;
    start = System.currentTimeMillis();
    for (int i = Integer.MIN_VALUE; i != Integer.MAX_VALUE; i++) {
        sum += bitCount(i);
        //sum += Integer.bitCount(i);
    }
    end = System.currentTimeMillis();
    System.out.println(sum);
    System.out.println(end - start);
}

private static int bitCount(int i) {
    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;
}
Run Code Online (Sandbox Code Playgroud)

// 对于 bitCount 结果

68719476736
8715
Run Code Online (Sandbox Code Playgroud)

// Integer.bitCount 结果

68719476736
1892
Run Code Online (Sandbox Code Playgroud)

Jac*_* G. 5

您的基准不准确。但无视这一点,一个原因是因为Integer#bitCount被标记为@HotSpotIntrinsicCandidate。这意味着 HotSpot JVM 可以用汇编代码替换方法体以提高性能。从注释的源代码

@HotSpotIntrinsicCandidate注释是特定的HotSpot虚拟机。它表示注解方法可能(但不保证)由 HotSpot VM 内在化。如果 HotSpot VM 用手写程序集和/或手写编译器 IR(编译器内在)替换带注释的方法以提高性能,则方法是内在化的。该@HotSpotIntrinsicCandidate注释是内部的Java库,因此不应该有任何的应用程序代码的相关性。

尝试禁用内部函数并再次运行测试;您应该会看到明显的放缓。