这是一个有趣的问题,我喜欢 @misiu_mp 的分析,所以我想用一台运行Android 6.0.1的Nexus 7进行2016年的测试来更新它。以下是测试代码:
public void runSpeedTest() {
long startTime;
long[] times = new long[100000];
long[] staticTimes = new long[100000];
for (int i = 0; i < times.length; i++) {
startTime = System.nanoTime();
for (int j = 0; j < 1000; j++) {
emptyMethod();
}
times[i] = (System.nanoTime() - startTime) / 1000;
startTime = System.nanoTime();
for (int j = 0; j < 1000; j++) {
emptyStaticMethod();
}
staticTimes[i] = (System.nanoTime() - startTime) / 1000;
}
int timesSum = 0;
for (int i = 0; i < times.length; i++) { timesSum += times[i]; Log.d("status", "time," + times[i]); sleep(); }
int timesStaticSum = 0;
for (int i = 0; i < times.length; i++) { timesStaticSum += staticTimes[i]; Log.d("status", "statictime," + staticTimes[i]); sleep(); }
sleep();
Log.d("status", "final speed = " + (timesSum / times.length));
Log.d("status", "final static speed = " + (timesStaticSum / times.length));
}
private void sleep() {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void emptyMethod() { }
private static void emptyStaticMethod() { }
sleep()
函数被添加以防止 Log.d
缓冲区溢出。
我多次尝试过它,结果与 @misiu_mp 的结果非常一致:
10^5 iterations of 1000 calls to an empty static void function: 29ns/call
10^5 iterations of 1000 calls to an empty non-static void function: 34ns/call
静态方法调用始终比非静态方法调用稍快,但似乎自Android 2.3.2以来,差距已经显著缩小,并且无论是静态方法还是非静态方法,调用空方法仍然需要付出代价。然而,查看时间直方图会发现有趣的事情。大多数调用(无论是静态还是非静态)都在30-40ns之间,仔细观察数据,它们几乎都是精确的30ns。
使用空循环运行相同的代码(注释掉方法调用)会产生平均速度为8ns,但是约有3/4的测量时间为0ns,其余时间恰好为30ns。我不确定如何解释这些数据,但我不确定@misiu_mp的结论是否仍然成立。空静态方法和非静态方法之间的差异微不足道,并且大部分测量值恰好为30ns。话虽如此,似乎仍然存在运行空方法的一些非零成本。