倒数还是向上计数,哪一个更快? [英] Counting down or Counting up, Which one is faster?
问题描述
可能重复:
在Java中,这些代码中的哪些代码更快?
如果我将循环写为
for (int i=n; i>=0; i--)
其他为
for (int i=0; i<=n; i++)
在Java中哪个会更快,为什么?..说 n = 10000
In java which one would be faster and why?..Say n=10000
推荐答案
使用Google Caliper进行查找.由于围绕零与上限,递增与递减的相对权重进行了很多讨论,因此,这是所有这些情况的笛卡尔积:
Never wonder; use Google Caliper to find out. Since there has been quite a bit of discussion around the relative weights of testing against zero vs. upper limit and incrementing vs. decrementing, here's the Cartesian product of all these cases:
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相比影响较小.
Apparently, whether the limit is zero or not has less effect than using inc vs. dec.
要指出这些差异有多弱,这里实际上是相同的代码,但是现在它使用了 long
(我在第一个示例中包括了一个方法,以保持规模):
To point out just how tenouous these differences are, here's virtually the same code, but now it uses long
s (I include one method from the first example, to maintain scale):
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 ==============================
主要结论:在如此低的水平下,绝不要对性能做任何假设.编写完整的代码并对其进行整体测试,因为总会有一些您没有考虑到的东西,这完全变成了表格.
Main conclusion: never assume anything about performance at such a low level. Write your full code and test it as a whole because there will always be something else you are not taking into account, which completely turns the tables.
这篇关于倒数还是向上计数,哪一个更快?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!