如何获得方法的执行时间? 是否有Timer实用程序类来计时任务所需的时间等?

在谷歌上的大多数搜索都返回调度线程和任务的计时器的结果,这不是我想要的。


当前回答

System.currentTimeMillis ();并不是衡量算法性能的好方法。它衡量的是你作为用户看电脑屏幕的总时间。它还包括在您的计算机上运行的所有其他事情所消耗的时间。如果您的工作站上运行了许多程序,这可能会产生巨大的不同。

正确的方法是使用java.lang.management包。

来自http://nadeausoftware.com/articles/2008/03/java_tip_how_get_cpu_and_user_time_benchmarking网站(档案链接):

“用户时间”是运行应用程序自己的代码所花费的时间。 “系统时间”是代表应用程序运行操作系统代码所花费的时间(例如用于I/O)。

getCpuTime()方法给出了它们的和:

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;

public class CPUUtils {

    /** Get CPU time in nanoseconds. */
    public static long getCpuTime( ) {
        ThreadMXBean bean = ManagementFactory.getThreadMXBean( );
        return bean.isCurrentThreadCpuTimeSupported( ) ?
            bean.getCurrentThreadCpuTime( ) : 0L;
    }

    /** Get user time in nanoseconds. */
    public static long getUserTime( ) {
        ThreadMXBean bean = ManagementFactory.getThreadMXBean( );
        return bean.isCurrentThreadCpuTimeSupported( ) ?
            bean.getCurrentThreadUserTime( ) : 0L;
    }

    /** Get system time in nanoseconds. */
    public static long getSystemTime( ) {
        ThreadMXBean bean = ManagementFactory.getThreadMXBean( );
        return bean.isCurrentThreadCpuTimeSupported( ) ?
            (bean.getCurrentThreadCpuTime( ) - bean.getCurrentThreadUserTime( )) : 0L;
    }

}

其他回答

JEP 230:微基准测试套件

供参考,JEP 230: Microbenchmark Suite是一个OpenJDK项目,用于:

向JDK源代码中添加一套基本的微基准测试,使开发人员可以轻松地运行现有的微基准测试和创建新的微基准测试。

这个特性是在Java 12中出现的。

Java微基准测试工具(JMH)

对于Java的早期版本,请查看JEP 230所基于的Java Microbenchmark Harness (JMH)项目。

我的答案很简单。对我有用。

long startTime = System.currentTimeMillis();

doReallyLongThing();

long endTime = System.currentTimeMillis();

System.out.println("That took " + (endTime - startTime) + " milliseconds");

它运行得很好。分辨率显然只有毫秒级,使用System.nanoTime()可以做得更好。这两种方法都有一些限制(操作系统调度切片等),但效果很好。

平均几次运行(越多越好),你就会得到一个不错的想法。

正如“skaffman”所说,使用AOP或您可以使用运行时字节码编织,就像使用单元测试方法覆盖工具透明地向调用的方法添加计时信息一样。

您可以查看开源工具(如Emma (http://downloads.sourceforge.net/emma/emma-2.0.5312-src.zip?modtime=1118607545&big_mirror=0))使用的代码。另一个开源覆盖工具是http://prdownloads.sourceforge.net/cobertura/cobertura-1.9-src.zip?download。

如果你最终做到了你所设定的目标,请用你的ant task/jars与社区分享。

new Timer(""){{
    // code to time 
}}.timeMe();



public class Timer {

    private final String timerName;
    private long started;

    public Timer(String timerName) {
        this.timerName = timerName;
        this.started = System.currentTimeMillis();
    }

    public void timeMe() {
        System.out.println(
        String.format("Execution of '%s' takes %dms.", 
                timerName, 
                started-System.currentTimeMillis()));
    }

}

您可以使用Metrics库,它提供了各种测量工具。添加依赖关系:

<dependencies>
    <dependency>
        <groupId>io.dropwizard.metrics</groupId>
        <artifactId>metrics-core</artifactId>
        <version>${metrics.version}</version>
    </dependency>
</dependencies>

并为您的环境配置它。

方法可以用@Timed进行注释:

@Timed
public void exampleMethod(){
    // some code
}

或者用Timer包装的一段代码:

final Timer timer = metricsRegistry.timer("some_name");
final Timer.Context context = timer.time();
// timed code
context.stop();

聚合的指标可以导出到控制台、JMX、CSV或其他。

@定时指标输出示例:

com.example.ExampleService.exampleMethod
             count = 2
         mean rate = 3.11 calls/minute
     1-minute rate = 0.96 calls/minute
     5-minute rate = 0.20 calls/minute
    15-minute rate = 0.07 calls/minute
               min = 17.01 milliseconds
               max = 1006.68 milliseconds
              mean = 511.84 milliseconds
            stddev = 699.80 milliseconds
            median = 511.84 milliseconds
              75% <= 1006.68 milliseconds
              95% <= 1006.68 milliseconds
              98% <= 1006.68 milliseconds
              99% <= 1006.68 milliseconds
            99.9% <= 1006.68 milliseconds