如何计算Java程序的执行速度

时间:2010-04-03 22:24:21

标签: java

你如何计算java程序的执行时间?我不确定我应该用什么课来做这件事。

我正在寻找类似的东西:

// Some timer starts here
for (int i = 0; i < length; i++) {
  // Do something
}
// End timer here

System.out.println("Total execution time: " + totalExecutionTime);

14 个答案:

答案 0 :(得分:127)

final long startTime = System.currentTimeMillis();
for (int i = 0; i < length; i++) {
  // Do something
}
final long endTime = System.currentTimeMillis();

System.out.println("Total execution time: " + (endTime - startTime));

答案 1 :(得分:33)

请注意,存在一些问题,System#nanoTime()无法在多核CPU上可靠地使用以记录经过的时间......每个核心都维护着自己的TSC(Time Stamp Counter):此计数器是用于获取纳米时间(实际上它是自CPU启动以来的滴答数)。

因此,除非操作系统进行一些TSC时间扭曲以保持内核同步,否则如果在执行初始时间读取时在一个内核上调度线程,然后切换到另一个内核,则偶尔会出现相对时间向前和向后跳。

我前段时间在AMD / Solaris上观察过这种情况,两个时间点之间的经过时间有时会以负值或意外大的正数回归。强制AMD PowerNow需要Solaris内核补丁和BIOS设置!关闭,似乎解决了它。

此外,在VirtualBox环境中使用java System#nanoTime()时,(AFAIK)存在一个迄今为止未修复的错误;因为java.util.concurrency包依赖于纳米时间,因此导致我们出现各种奇怪的间歇性线程问题。

另见:

Is System.nanoTime() completely useless?  http://vbox.innotek.de/pipermail/vbox-trac/2010-January/135631.html

答案 2 :(得分:9)

您可以使用System#nanoTime()。在执行之前和之后获取它并进行数学运算。它优先于System#currentTimeMillis(),因为它具有更好的精度。根据所使用的硬件和平台,您可能会在经过的时间内获得不正确的间隙。在Windows上使用Core2Duo,在大约0到~15ms之间实际上无法计算任何内容。

更高级的工具是profiler

答案 3 :(得分:7)

您将获得当前系统时间,以毫秒为单位:

final long startTime = System.currentTimeMillis();

然后你做你要做的事情:

for (int i = 0; i < length; i++) {
  // Do something
}

然后你看看花了多长时间:

final long elapsedTimeMillis = System.currentTimeMillis() - startTime;

答案 4 :(得分:3)

对于简单的东西, System.currentTimeMillis()可以工作。

我的IDE设置实际上是如此常见,以便在输入“t0”时它会生成以下行:

final long t0 = System.currentTimeMillis()

但是对于更复杂的事情,你可能想要使用统计时间测量,比如这里(向下滚动一下并查看表达的时间测量值,包括标准偏差等):

http://perf4j.codehaus.org/devguide.html

答案 5 :(得分:2)

使用@Loggable中的AOP / AspectJ和jcabi-aspects注释,您可以轻松简洁地完成:

@Loggable(Loggable.DEBUG)
public String getSomeResult() {
  // return some value
}

对此方法的每次调用都将发送到具有DEBUG日志记录级别的SLF4J日志记录工具。每条日志消息都包含执行时间。

答案 6 :(得分:1)

使用长startTime=System.currentTimeMillis()作为开始时间,位于循环顶部

long endTime= System.currentTimeMillis();放在循环结束之外。您必须以毫秒为单位减去值以获得运行时。

如果您想要以纳秒为单位的时间,请查看System.nanoTime()

答案 7 :(得分:1)

有几种方法可以找到Java中的执行时间:

1)System.nanoTime()

long startTime = System.nanoTime();
.....your code....
long endTime   = System.nanoTime();
long totalTime = endTime - startTime;
System.out.println("Execution time in nanoseconds  : " + totalTime);
System.out.println("Execution time in milliseconds : " + totalTime / 1000000);

2)System.currentTimeMillis()

long startTime = System.currentTimeMillis();
.....your code....
long endTime = System.currentTimeMillis();
long totalTime = endTime - startTime;
System.out.println("Execution time in milliseconds  : " + totalTime);

3)Instant.now()

long startTime = Instant.now().toEpochMilli();
.....your code....
long endTime = Instant.now().toEpochMilli();
long totalTime = endTime - startTime;
System.out.println("Execution time in milliseconds: " + totalTime);

Instant start = Instant.now();
.....your code....
Instant end = Instant.now();
Duration interval = Duration.between(start, end);
System.out.println("Execution time in seconds: " +interval.getSeconds());

4)Date.getTime()

long startTime = new Date().getTime();
.....your code....
long endTime = new Date().getTime();
long totalTime = endTime - startTime;
System.out.println("Execution time in milliseconds: " + totalTime);

答案 8 :(得分:1)

我创建了一个高阶函数,该函数将您要测量的代码作为/作为lambda:

class Utils {

    public static <T> T timeIt(String msg, Supplier<T> s) {
        long startTime = System.nanoTime();
        T t = s.get();
        long endTime = System.nanoTime();
        System.out.println(msg + ": " + (endTime - startTime) + " ns");
        return t;
    }

    public static void timeIt(String msg, Runnable r) {
       timeIt(msg, () -> {r.run(); return null; });
    }
}

这样称呼:

Utils.timeIt("code 0", () ->
        System.out.println("Hallo")
);

// in case you need the result of the lambda
int i = Utils.timeIt("code 1", () ->
        5 * 5
);

输出:

  

代码0:180528 ns
  代码1:12003 ns

特别感谢Andy Turner帮助我减少了冗余。参见here

答案 9 :(得分:1)

您可以使用秒表

import com.google.common.base.Stopwatch;

Stopwatch timer = Stopwatch.createStarted();
//lines to be executed
System.out.println("Execution time= " + timer.stop());

答案 10 :(得分:0)

答案 11 :(得分:0)

public class someClass
{
   public static void main(String[] args) // your app start point
   {
       long start = java.util.Calendar.getInstance().getTimeInMillis();

       ... your stuff ...

       long end = java.util.Calendar.getInstance().getTimeInMillis();
       System.out.println("it took this long to complete this stuff: " + (end - start) + "ms");
   }
}

答案 12 :(得分:0)

您也可以尝试Perf4J。它是一种简洁的方式来处理您正在寻找的内容,并有助于在设定的时间跨度内汇总性能统计数据,如平均值,最小值,最大值,标准差和每秒事务数。来自http://perf4j.codehaus.org/devguide.html的摘录:

StopWatch stopWatch = new LoggingStopWatch();

try {
    // the code block being timed - this is just a dummy example
    long sleepTime = (long)(Math.random() * 1000L);
    Thread.sleep(sleepTime);
    if (sleepTime > 500L) {
        throw new Exception("Throwing exception");
    }

    stopWatch.stop("codeBlock2.success", "Sleep time was < 500 ms");
} catch (Exception e) {
    stopWatch.stop("codeBlock2.failure", "Exception was: " + e);
}

输出:

INFO: start[1230493236109] time[447] tag[codeBlock2.success] message[Sleep time was < 500 ms]
INFO: start[1230493236719] time[567] tag[codeBlock2.failure] message[Exception was: java.lang.Exception: Throwing exception]
INFO: start[1230493237286] time[986] tag[codeBlock2.failure] message[Exception was: java.lang.Exception: Throwing exception]
INFO: start[1230493238273] time[194] tag[codeBlock2.success] message[Sleep time was < 500 ms]
INFO: start[1230493238467] time[463] tag[codeBlock2.success] message[Sleep time was < 500 ms]
INFO: start[1230493238930] time[310] tag[codeBlock2.success] message[Sleep time was < 500 ms]
INFO: start[1230493239241] time[610] tag[codeBlock2.failure] message[Exception was: java.lang.Exception: Throwing exception]
INFO: start[1230493239852] time[84] tag[codeBlock2.success] message[Sleep time was < 500 ms]
INFO: start[1230493239937] time[30] tag[codeBlock2.success] message[Sleep time was < 500 ms]
INFO: start[1230493239968] time[852] tag[codeBlock2.failure] message[Exception was: java.lang.Exception: Throwing exception]

答案 13 :(得分:0)

使用System.currentTimeMillis()是执行此操作的正确方法。但是,如果您使用命令行,并且想要大致且快速地对整个程序计时,请考虑:

time java App

允许您不要修改应用程序的代码和时间。