测量执行代码所花费的时间

时间:2016-11-22 07:04:42

标签: java for-loop time-complexity

让我说我有以下循环,我想要时间:

for(int i = 0; i < list.size() - 1; i++ ) {     
{
// call other methods, let's say call other 3-4 methods

}

因此,如果我想测量在for循环之前和之后使用内置Java long time = System.nanoTime();运行循环的时间,它还会测量我在方法中花费的时间吗?我打电话?

或者,如果我没有调用其他方法并将所有代码放在for循环中,那么如果我只是调用其他方法则需要更多时间?

3 个答案:

答案 0 :(得分:1)

计时器只计算它开始和结束之间的差异。它不知道开始和结束之间发生了什么。因此,如果将所有代码转储到for循环中,或者直接调用这些方法而不是内联它们,则无关紧要。

然而,这不会给你每个功能所花费的时间。您可能希望查看Java profilers以更系统的方式获得结果。

答案 1 :(得分:0)

System.nanoTime()返回正在运行的Java虚拟机的高分辨率时间源的当前值,以纳秒为单位。

来自Java的文档:

  

此方法只能用于测量经过的时间而不是   与系统或挂钟时间的任何其他概念有关。价值   返回表示自某些固定但任意来源以来的纳秒   时间(也许在将来,所以价值可能是负面的)。相同   在a的实例中,此方法的所有调用都使用origin   Java虚拟机;其他虚拟机实例很可能   使用不同的来源。

使用System.nanoTime()值计算时间将计算执行该循环所需的全部时间。这将包括循环内方法的执行时间(如果它们在那里)。

但是,如果您在循环内启动具有自己执行时间的线程,则从第1点到第2点所经过的时间将只是启动线程所花费的时间,而不是它们的执行时间。

我找到了理解这件事的好方法。只需编写一个简单的代码:

long t1 = System.nanoTime();
long t2 = System.nanoTime();
System.out.println((t2 - t1) / 1000000);
  1. 在调试器中将其拉出来,看看当你不应用任何断点时会发生什么。

  2. 现在在第2行应用断点并等待一段时间再恢复执行。

  3. 你可以看到差异。

    Reference Link

答案 2 :(得分:0)

这是一个简单的例子,说明我将用什么做一些基本的而不是精确的测试。

我们首先需要一些基本方法来轻松启动和打印时间

public class Main {

    static long start;

    static void startTest(){
        start = System.nanoTime();
    }

    static void stopTest(){
        System.out.format("%012.6f ms\n",(System.nanoTime() - start)/1000000.0);
        start = -1;
    }
}

单线程

让我们在空循环上运行测试:

startTest();
for(int i = 0; i < Integer.MAX_VALUE; ++i){}
stopTest();

这将在调用stopTest()之前等待循环结束并打印所需的时间。

多线程

使用不同的主题,您需要等待它们结束,这很简单,并且不能以多种方式进行。这是一个:

startTest();
List<Callable<String>> list = new ArrayList();
for(int i=0;i<5;i++){
    list.add(new Callable() {
        public Object call() throws Exception {
            for(int i = 0; i < Integer.MAX_VALUE/5; ++i){}
            System.out.println("End of Thread");
            return null;
        }
    });
}
ExecutorService es = Executors.newCachedThreadPool();
try {

    es.invokeAll(list);
} catch (InterruptedException ex) {
    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
} finally {
    stopTest();
    es.shutdown();
}

使用此Executors,我们可以在等待它们结束的同时调用所有Callable