繁体   English   中英

使用System.currentTimeMillis()时出现问题; 在Java中

[英]Problem in using System.currentTimeMillis(); in Java

在第n个斐波那契数的计算中,我尝试观察不同输入所花费的时间,但是第一个输入的输出<50ms,其余输入的输出为0ms,为什么呢?

import java.io.*;
import java.util.*;
class fib{
    long fibo(int s){
        if(s==1 ||s==2)
        return 1;
        else return fibo(s-1)+(s-2);
    }
}
class fibrec{
    public static void main(String args[]) throws java.io.IOException{
        BufferedWriter wr=new BufferedWriter(new FileWriter("C:/Users/91887/desktop/books/java/foo3.txt"));
        fib f=new fib();
        Random rand=new Random();
        int input[]=new int[10];
        for(int p=0;p<10;p++){
            long st=System.currentTimeMillis();
            int i=rand.nextInt(12000);
            wr.write("Input : "+i+"\nOutput : "+f.fibo(i)+"\n");
            long et=System.currentTimeMillis();
            wr.write("Time taken = "+(et-st)+"ms\n\n");
            System.out.println(st+"\t"+et+"\t"+(et-st));
        }

        wr.close();
    }
}

毫秒时钟的粒度最多1毫秒1

但是很明显,循环迭代的执行时间不到一毫秒。 使用System.currentTimeMillis()无法精确测量毫秒以下的时间间隔。 这就是为什么您得到零。

第一次测量的解释是35毫秒,这是由于JVM预热效应引起的。 这些可能包括:

  • 加载和初始化库代码2所需的时间
  • JIT编译代码所花费的时间,以及
  • 在加载和JIT编译期间或之后,(可能)GC占用的时间。

其次,我注意到您的时间量度包括打印数字所花费的时间。 您应该在第二次调用之后将其移动以获取时钟值,因为它可能很重要。

最后,如果要获得可重现的结果,则应自己明确为“ Random种子,而不要依靠操作系统为您提供随机种子。 而且我不认为您还是应该使用随机输入来对Fibonacci算法进行基准测试...


1-输出中的数字表明实际上是1毫秒...

2-例如, Random实例的初始化和构造需要进行OS调用以获得一些“熵”,以为随机数生成器提供种子。 应该很快,但是在某些情况下可能并非如此。 就您而言,这发生在您开始测量时间之前...

两次调用System.currentTimeMillis()之间的代码执行速度太快(第一次迭代后),无法捕获任何差异。 如果您使用System.nanoTime()则可以看到不同之处。

至于为什么第一次迭代要慢于随后的迭代,那是因为Java使用即时(JIT)编译器在运行时优化代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM