倒数还是向上计数,哪一个更快? [英] Counting down or Counting up, Which one is faster?

查看:57
本文介绍了倒数还是向上计数,哪一个更快?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可能重复:
在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 longs (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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆