2012-07-11 94 views
1

当测试的答案,我related questions之一,我写了这个:为什么要添加一行计算减少运行时间?

public static long timeDouble(int iters) { 
    long start = System.currentTimeMillis(); 
    for (; iters >=0; iters--) { 
     double a = 1.2, b = 2.246, c = 4.4924, d = 8.98488, e = 17.969772; 
     a = Math.sqrt(a); 
     b = Math.cos(b); 
     c = Math.sin(c); 
     d = Math.tan(d); 
     e = a + b - c * d/(e + 1); 
     e = Math.pow(e, e); 
    } 
    return System.currentTimeMillis() - start; 
} 

这种方法的运行时间为414ms的平均(使用百万次迭代)。然而,有些东西附身我加入这行:

e = e + d - c * b/(a + 1); 

之前e = Math.pow(e, e);在加入这一行的,为了计算这种方法的时候下降到平均206毫秒(使用相同的测试条件下)。

这是什么造成的?

+1

也许'e'的值被这个等式减少了,然后'Math.pow(e,e)'将花费更少的时间来执行。 – 2012-07-11 16:24:45

+3

这可能是由于Math.pow(e,e)使用较少的处理器周期这一事实,也许是由于e较小的事实。 – 2012-07-11 16:25:16

+2

上面的海报可能是正确的,但我通常会偏离这种微基准,它有很多缺陷。 http://www.kdgregory.com/index.php?page=java.microBenchmark – Thor84no 2012-07-11 16:29:12

回答

3

循环中的值是常量,它们不取决于iters。因此这些值始终保持一致。

double a = 1.2, b = 2.246, c = 4.4924, d = 8.98488, e = 17.969772; 
    a = Math.sqrt(a); 
    b = Math.cos(b); 
    c = Math.sin(c); 
    d = Math.tan(d); 
    e = a + b - c * d/(e + 1); 
    e = Math.pow(e, e); 

在第一个版本你计算e是价值17.969772^17.969772。在第二个你计算e是值0.69761863561124537^0.69761863561124537。这是(通过你自己的证据)更容易计算机。