【问题标题】:Why does the processor take the same amount of time to execute these two for loops (coded in Java)?为什么处理器执行这两个 for 循环(用 Java 编码)花费相同的时间?
【发布时间】:2012-11-06 10:45:59
【问题描述】:
public class FactorFinder{
  public static void main(String[] args) {      
    long n = ((long)Integer.MAX_VALUE+1)*2;
    boolean isPrime=true;

    for(long i=2;i<=n/2;i++){
        if(n%i==0){
            System.out.println(i + " is a factor of " + n);
            isPrime = false;
        }   
    }    
    if(isPrime == true) System.out.println(n+ " is a prime number");   
  }     
}      

我编写了上面的代码来查找因子 n,或者如果它没有任何因子,则打印“n 是质数”。 我在代码中临时设置了 n=2^32 以查看程序完全运行需要多长时间。耗时 1 分 17 秒。

然后我将for循环更改为

for(long i=2;i<n;i++){

并预计完成该程序所需的时间是原来的两倍。如您所料,既然您已经阅读了我的问题,只用了 1 分 17 秒。

我是否认为处理器能够以某种方式知道在 n 大于 2^32 / 2 之后,它不再需要运行循环,或者即使它运行了,它也没有再检查 if 语句的条件?

我有一个 Intel core i3,JDK 1.7.0 在 Windows 7 上运行。

【问题讨论】:

    标签: java performance time for-loop processor


    【解决方案1】:

    如果编译器不尝试执行不必要的计算,那就很聪明了,因为没有必要检查 n 是否可被 i 整除,如果 i > root(n)

    【讨论】:

      【解决方案2】:

      我的机器上的 n/2 版本花费了一半的时间。编译器不可能足够聪明,无法弄清楚您正在考虑的优化类型。

      你记得在第二次测试之前保存源文件并重新编译吗?忘记这一点可以解释你得到的结果,我想不出还有什么可以解释的。

      【讨论】:

      • 我一开始也是这么想的。但我确实保存并编译。我什至改变了IDE。请告诉我你有什么样的处理器?
      • 它不可能是处理器。如果是优化,那一定是 Java 编译器。
      • 由于分支预测,我认为它可能是处理器。参见这里,stackoverflow.com/questions/11227809/… 和这里 en.wikipedia.org/wiki/Branch_predictor 简单地说,分支预测是当处理器可以“习惯”在很长一段时间内做出相同的决定时做出决定,所以处理器,而不是进行计算做出决定,需要猜测。
      • 没有一个分支预测器会足够聪明地推断程序将来会做什么,并意识到由于复杂的数学原因,代码告诉它计算的东西是不必要的。编译器可能会进行这样的优化。我再次尝试使用 jdk 1.7(我一直在使用 1.6)并得到了相同的结果。一些 IDE 有自己的编译器,所以不妨尝试从命令行编译和运行它。
      • @Micael Shaw 好吧,我认为分支预测器不必意识到我的“代码告诉它计算的内容是不必要的”,并且它不必知道这里涉及的数学原因。它所要做的就是查看 i>n/2 之后的计算历史,它可以很好地猜测 i 的下一个值的条件是否为假。这就是分支预测器的作用,它查看决策历史并在一般情况下做出 90% 的准确猜测。在我的代码中,准确率是 100%,不是吗?
      猜你喜欢
      • 1970-01-01
      • 2021-11-19
      • 2019-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多