简体   繁体   English

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

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

I tried to observe the time taken by different inputs in the calculation of the nth Fibonacci number, but the output is <50ms for the first input and 0 ms for the rest Why so? 在第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();
    }
}

The granularity of the millisecond clock is at best one millisecond 1 . 毫秒时钟的粒度最多1毫秒1

But apparently, the execution times for your loop iterations are less than one millisecond. 但是很明显,循环迭代的执行时间不到一毫秒。 Sub-millisecond time intervals cannot be measured accurately using System.currentTimeMillis() . 使用System.currentTimeMillis()无法精确测量毫秒以下的时间间隔。 That is why you are getting zeros. 这就是为什么您得到零。

The explanation for the first measurement being 35 milliseconds is that this is due to JVM warmup effects. 第一次测量的解释是35毫秒,这是由于JVM预热效应引起的。 These may include: 这些可能包括:

  • time taken to load and initialize library code 2 , 加载和初始化库代码2所需的时间
  • time taken to JIT compile code, and JIT编译代码所花费的时间,以及
  • time taken up with a (possible) GC during or after loading and JIT compilation. 在加载和JIT编译期间或之后,(可能)GC占用的时间。

Secondly, I notice that your time measurement includes the time taken to print the number. 其次,我注意到您的时间量度包括打印数字所花费的时间。 You should move that after the second call to get the clock value because it could be significant. 您应该在第二次调用之后将其移动以获取时钟值,因为它可能很重要。

Finally, it you want to get reproducible results, you should explicitly seed Random yourself rather than relying on the OS to give you a random seed. 最后,如果要获得可重现的结果,则应自己明确为“ Random种子,而不要依靠操作系统为您提供随机种子。 And I'm not convinced that you should be benchmarking a Fibonacci algorithm with random inputs anyway ... 而且我不认为您还是应该使用随机输入来对Fibonacci算法进行基准测试...


1 - The numbers in your output suggest that it is actually 1 millisecond ... 1-输出中的数字表明实际上是1毫秒...

2 - For example, the initialization and construction of a Random instance entails an OS call to get some "entropy" to seed the random number generator. 2-例如, Random实例的初始化和构造需要进行OS调用以获得一些“熵”,以为随机数生成器提供种子。 That should be fast, but there are circumstances where it may not be. 应该很快,但是在某些情况下可能并非如此。 In your case, this happens before you start measuring time ... 就您而言,这发生在您开始测量时间之前...

The code between the two calls to System.currentTimeMillis() is executing too fast (after the first iteration) for any difference to be captured. 两次调用System.currentTimeMillis()之间的代码执行速度太快(第一次迭代后),无法捕获任何差异。 You'd be able to see a difference if you were using System.nanoTime() . 如果您使用System.nanoTime()则可以看到不同之处。

As for why the first iteration is slower than the subsequent ones, that would be because Java uses a Just In Time (JIT) compiler to optimise code at runtime. 至于为什么第一次迭代要慢于随后的迭代,那是因为Java使用即时(JIT)编译器在运行时优化代码。

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

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