永远不要怀疑;用谷歌卡尺找出来。由于围绕零与上限以及递增与递减测试的相对权重进行了相当多的讨论,以下是所有这些情况的笛卡尔积:
import java.util.Random;
import com.google.caliper.Runner;
import com.google.caliper.SimpleBenchmark;
public class Performance extends SimpleBenchmark {
static final Random rnd = new Random();
public int timeDecrementToZero(int reps) {
int sum = rnd.nextInt();
for (int i = 0; i < reps; i++) {
for (int j = Integer.MAX_VALUE; j >= 0; j--) sum += j;
}
return sum;
}
public int timeDecrementFromZero(int reps) {
int sum = rnd.nextInt();
for (int i = 0; i < reps; i++) {
for (int j = 0; j > Integer.MIN_VALUE; j--) sum += j;
}
return sum;
}
public int timeIncrementFromZero(int reps) {
int sum = rnd.nextInt();
for (int i = 0; i < reps; i++) {
for (int j = 0; j < Integer.MAX_VALUE; j++) sum += j;
}
return sum;
}
public int timeIncrementToZero(int reps) {
int sum = rnd.nextInt();
for (int i = 0; i < reps; i++) {
for (int j = Integer.MIN_VALUE; j < 0; j++) sum += j;
}
return sum;
}
public static void main(String... args) {
Runner.main(Performance.class, args);
}
}
结果:
0% Scenario{vm=java, trial=0, benchmark=DecrementToZero} 984060500.00 ns; σ=30872487.22 ns @ 10 trials
25% Scenario{vm=java, trial=0, benchmark=DecrementFromZero} 982646000.00 ns; σ=35524893.00 ns @ 10 trials
50% Scenario{vm=java, trial=0, benchmark=IncrementFromZero} 1023745500.00 ns; σ=24828496.82 ns @ 10 trials
75% Scenario{vm=java, trial=0, benchmark=IncrementToZero} 1081112500.00 ns; σ=20160821.13 ns @ 10 trials
benchmark ms linear runtime
DecrementToZero 984 ===========================
DecrementFromZero 983 ===========================
IncrementFromZero 1024 ============================
IncrementToZero 1081 ==============================
显然,无论限制是否为零,其效果都比使用 inc 与 dec 的效果要小。
让我们稍微改变一下...
为了指出这些差异有多么微妙,这里的代码几乎相同,但现在它使用longs(我包括第一个示例中的一个方法,以保持规模):
public int timeDecrementFromZeroInt(int reps) {
int sum = rnd.nextInt();
for (int i = 0; i < reps; i++) {
for (int j = 0; j > Integer.MIN_VALUE; j--) sum += j;
}
return sum;
}
public long timeDecrementFromZero(int reps) {
long sum = rnd.nextLong();
for (long i = 0; i < reps; i++) {
for (long j = 0; j > Integer.MIN_VALUE; j--) sum += j;
}
return sum;
}
public long timeIncrementFromZero(int reps) {
long sum = rnd.nextLong();
for (long i = 0; i < reps; i++) {
for (long j = 0; j < Integer.MAX_VALUE; j++) sum += j;
}
return sum;
}
public long timeDecrementToZero(int reps) {
long sum = rnd.nextLong();
for (long i = 0; i < reps; i++) {
for (long j = Integer.MAX_VALUE; j >= 0; j--) sum += j;
}
return sum;
}
public long timeIncrementToZero(int reps) {
long sum = rnd.nextLong();
for (long i = 0; i < reps; i++) {
for (long j = Integer.MIN_VALUE; j < 0; j++) sum += j;
}
return sum;
}
结果:
0% Scenario{vm=java, trial=0, benchmark=DecrementFromZeroInt} 978513000.00 ns; σ=14861284.82 ns @ 10 trials
20% Scenario{vm=java, trial=0, benchmark=DecrementFromZero} 2160652000.00 ns; σ=13825686.87 ns @ 3 trials
40% Scenario{vm=java, trial=0, benchmark=IncrementFromZero} 2153370000.00 ns; σ=6318160.49 ns @ 3 trials
60% Scenario{vm=java, trial=0, benchmark=DecrementToZero} 4379893000.00 ns; σ=8739917.79 ns @ 3 trials
80% Scenario{vm=java, trial=0, benchmark=IncrementToZero} 4383569000.00 ns; σ=5798095.89 ns @ 3 trials
benchmark ms linear runtime
DecrementFromZeroInt 979 ======
DecrementFromZero 2161 ==============
IncrementFromZero 2153 ==============
DecrementToZero 4380 =============================
IncrementToZero 4384 ==============================
主要结论:永远不要在如此低的水平上对性能做出任何假设。编写完整的代码并对其进行整体测试,因为总会有一些你没有考虑到的东西,这完全颠覆了局面。