这是一个有趣的问题,我喜欢@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) {
// TODO Auto-generated catch block
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
静态方法调用总是比非静态方法调用稍快,但似乎 a) 自 Android 2.3.2 以来差距已大大缩小,b) 调用空方法仍然需要成本,静态与否。
然而,查看时间直方图会发现一些有趣的事情。大多数调用,无论是否静态,都需要 30-40ns,仔细观察数据,它们几乎都是 30ns。
使用空循环运行相同的代码(注释掉方法调用)会产生 8ns 的平均速度,但是,大约 3/4 的测量时间是 0ns,而其余时间正好是 30ns。
我不确定如何解释这些数据,但我不确定@misiu_mp 的结论是否仍然成立。空静态和非静态方法之间的差异可以忽略不计,测量的优势正好是 30ns。话虽如此,运行空方法似乎仍有一些非零成本。