内联代码比Java中的函数调用/静态函数慢

ddu*_*kki 2 java inline function

我一直在运行一些测试来查看内联函数代码(在代码本身中显式编写函数算法)如何影响性能.我将一个简单的字节数组写入整数代码,然后将其包装在一个函数中,从另一个类中静态调用它,并从类本身静态调用它.代码如下:

public class FunctionCallSpeed {
    public static final int numIter = 50000000;

    public static void main (String [] args) {
        byte [] n = new byte[4];

        long start;

        System.out.println("Function from Static Class =================");
        start = System.nanoTime();
        for (int i = 0; i < numIter; i++) {
            StaticClass.toInt(n);
        }
        System.out.println("Elapsed time: " + (double)(System.nanoTime() - start) / 1000000000 + "s");

        System.out.println("Function from Class ========================");
        start = System.nanoTime();
        for (int i = 0; i < numIter; i++) {
            toInt(n);
        }
        System.out.println("Elapsed time: " + (double)(System.nanoTime() - start) / 1000000000 + "s");

        int actual = 0;

        int len = n.length;

        System.out.println("Inline Function ============================");
        start = System.nanoTime();
        for (int i = 0; i < numIter; i++) {
            for (int j = 0; j < len; j++) {
                actual += n[len - 1 - j] << 8 * j;
            }
        }
        System.out.println("Elapsed time: " + (double)(System.nanoTime() - start) / 1000000000 + "s");
    }

    public static int toInt(byte [] num) {
        int actual = 0;

        int len = num.length;

        for (int i = 0; i < len; i++) {
            actual += num[len - 1 - i] << 8 * i;
        }

        return actual;
    }
}
Run Code Online (Sandbox Code Playgroud)

结果如下:

Function from Static Class =================
Elapsed time: 0.096559931s
Function from Class ========================
Elapsed time: 0.015741711s
Inline Function ============================
Elapsed time: 0.837626286s
Run Code Online (Sandbox Code Playgroud)

字节码是否有奇怪的东西?我自己看了字节码,但我不是很熟悉,我不能做它的正面或反面.

编辑

我添加了assert语句来读取输出,然后随机化读取的字节,基准测试现在的行为与我认为的方式相同.感谢Tomasz Nurkiewicz,他向我指出了微基准文章.结果代码是:

public class FunctionCallSpeed {
public static final int numIter = 50000000;

public static void main (String [] args) {
    byte [] n;

    long start, end;
    int checker, calc;

    end = 0;
    System.out.println("Function from Object =================");
    for (int i = 0; i < numIter; i++) {
        checker = (int)(Math.random() * 65535);
        n = toByte(checker);
        start = System.nanoTime();
        calc = StaticClass.toInt(n);
        end += System.nanoTime() - start;
        assert calc == checker;
    }
    System.out.println("Elapsed time: " + (double)end / 1000000000 + "s");
    end = 0;
    System.out.println("Function from Class ==================");
    start = System.nanoTime();
    for (int i = 0; i < numIter; i++) {
        checker = (int)(Math.random() * 65535);
        n = toByte(checker);
        start = System.nanoTime();
        calc = toInt(n);
        end += System.nanoTime() - start;
        assert calc == checker;
    }
    System.out.println("Elapsed time: " + (double)end / 1000000000 + "s");


    int len = 4;
    end = 0;
    System.out.println("Inline Function ======================");
    start = System.nanoTime();
    for (int i = 0; i < numIter; i++) {
        calc = 0;
        checker = (int)(Math.random() * 65535);
        n = toByte(checker);
        start = System.nanoTime();
        for (int j = 0; j < len; j++) {
            calc += n[len - 1 - j] << 8 * j;
        }
        end += System.nanoTime() - start;
        assert calc == checker;
    }
    System.out.println("Elapsed time: " + (double)(System.nanoTime() - start) / 1000000000 + "s");
}

public static byte [] toByte(int val) {
    byte [] n = new byte[4];

    for (int i = 0; i < 4; i++) {
        n[i] = (byte)((val >> 8 * i) & 0xFF);
    }
    return n;
}

public static int toInt(byte [] num) {
    int actual = 0;

    int len = num.length;

    for (int i = 0; i < len; i++) {
        actual += num[len - 1 - i] << 8 * i;
    }

    return actual;
}
}
Run Code Online (Sandbox Code Playgroud)

结果:

Function from Static Class =================
Elapsed time: 9.276437031s
Function from Class ========================
Elapsed time: 9.225660708s
Inline Function ============================
Elapsed time: 5.9512E-5s
Run Code Online (Sandbox Code Playgroud)

cor*_*iKa 5

总是难以保证JIT正在做什么,但如果我不得不猜测,它注意到函数的返回值从未被使用过,并且优化了很多.

如果您实际使用函数的返回值,我敢打赌它会改变速度.