1、基本类型的前置++和后置++比较
private static void testPlus() {
final long loopCount = 1000000000L;
long start = 0L;
long finish = 0L;
long sum = 0L;
start = System.currentTimeMillis();
for (long i = 0L; i < loopCount; i++) {
sum += i;
}
finish = System.currentTimeMillis();
System.out.println("后置++ cost:" + (finish - start) + "ms, sum:" + sum);
sum = 0L;
start = System.currentTimeMillis();
for (long i = 0L; i < loopCount; ++i) {
sum += i;
}
finish = System.currentTimeMillis();
System.out.println("前置++ cost:" + (finish - start) + "ms, sum:" + sum);
}
测试结果:
后置++ cost:329ms, sum:499999999500000000
前置++ cost:328ms, sum:499999999500000000
其实通过javap工具观察字节码指令可以发现,基本类型的前置++和后置++的字节码指令是完全一样的,主要就是ladd。
2、包装类型的前置++和后置++比较
private static void testPlus2() {
final Long loopCount = 1000000000L;
Long start = 0L;
Long finish = 0L;
Long sum = 0L;
start = System.currentTimeMillis();
for (Long i = 0L; i < loopCount; i++) {
sum += i;
}
finish = System.currentTimeMillis();
System.out.println("后置++ cost:" + (finish - start) + "ms, sum:" + sum);
sum = 0L;
start = System.currentTimeMillis();
for (Long i = 0L; i < loopCount; ++i) {
sum += i;
}
finish = System.currentTimeMillis();
System.out.println("前置++ cost:" + (finish - start) + "ms, sum:" + sum);
}
测试结果:
后置++ cost:6493ms, sum:499999999500000000
前置++ cost:6294ms, sum:499999999500000000
其实通过javap工具观察字节码指令可以发现,包装类型的前置++和后置++的字节码指令比基本类型的复杂了许多,主要是增加了一些装箱拆箱的指令。包装类型的后置++又比前置++多几条指令,主要是dup指令复制出数据缓存起来,但是测试的结果却基本相同,所以猜测是不是一般场景下JVM有相关的优化。
3、总结
由测试结果看,前置++是要比后置++效率更高一点点。但其实十亿次的运算,差距也不大,这个可能是在一般场景下JVM有相关优化,所以其实很多时候大可不必纠结是应该用前置++还是后置++。
从1、2横向对比看,包装类型的运算效率要比基本类型相差很多,这个涉及到包装类的自动装箱和拆箱,肯定是要吃性能的,所以能用基本类型的地方应该尽量用基本类型,比如局部变量没有特殊情况就应该用基本类型。