我最近开始对一些Java代码进行基准测试,以使程序获得最佳性能,并注意到了一些奇怪的事情。即,我已经对以下方法进行了基准测试:
private static final int n = 10000;
public static void test0(){
int m = 0;
for(int i = 0; i < n; ++i){
m = Math.max(i, m);
}
}
public static void test1(){
int m = 0;
for(int i = 0; i < n; ++i){
m = ((i >= m) ? i : m);
}
}
得到了那些结果:
| Test 0 | Test 1 |
----------+-----------------+-----------------+-
Average: | 51,77 ns | 13956,63 ns |
Best: | 0,00 ns | 6514,00 ns |
Worst: | 25,45 ms | 60,50 ms |
Tries: | 16971233 | 16971233 |
在SO上搜索之后(即Java中Math.max(a,b)或(a> b)?a:b更快吗?),对我来说肯定test1
不会那么慢。
这些方法在30秒内在8个线程上进行了随机测试,我运行的每个基准测试似乎都相似。我用jdk1.8.0_45
。
那么,为什么test1
慢200倍test0
?
由于Math.max
是静态函数,编译器可能会发现代码根本不执行任何操作,而只是通过不执行代码来优化执行!
变量m
是函数的局部变量,对其进行分配无济于事,因为它永远不会被读取。
您需要确保执行以某种方式修改了某些内容,以便编译器不会主动对其进行优化。
例如,您可以m
在测试结束时简单地打印的值,或者制作m
一个可以稍后访问的类变量,甚至可以像我最初在注释中建议的那样对结果求和。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句