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

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


当前回答

JEP 230:微基准测试套件

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

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

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

Java微基准测试工具(JMH)

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

其他回答

对于java 8+,另一种可能的解决方案(更通用,函数风格,没有方面)可能是创建一些实用程序方法,将代码作为参数接受

public static <T> T timed (String description, Consumer<String> out, Supplier<T> code) {
    final LocalDateTime start = LocalDateTime.now ();
    T res = code.get ();
    final long execTime = Duration.between (start, LocalDateTime.now ()).toMillis ();
    out.accept (String.format ("%s: %d ms", description, execTime));
    return res;
}

调用代码可以是这样的smth:

public static void main (String[] args) throws InterruptedException {
    timed ("Simple example", System.out::println, Timing::myCode);
}

public static Object myCode () {
    try {
        Thread.sleep (1500);
    } catch (InterruptedException e) {
        e.printStackTrace ();
    }
    return null;
}

我实现了一个简单的定时器,我认为它真的很有用:

public class Timer{
    private static long start_time;

    public static double tic(){
        return start_time = System.nanoTime();
    }

    public static double toc(){
        return (System.nanoTime()-start_time)/1000000000.0;
    }

}

这样你就可以计算一个或多个动作的时间:

Timer.tic();
// Code 1
System.out.println("Code 1 runtime: "+Timer.toc()+" seconds.");
// Code 2
System.out.println("(Code 1 + Code 2) runtime: "+Timer.toc()+"seconds");
Timer.tic();
// Code 3
System.out.println("Code 3 runtime: "+Timer.toc()+" seconds.");

这可能不是您想让我说的,但是这是AOP的一个很好的用法。在您的方法周围使用代理拦截器,并在其中进行计时。

遗憾的是,AOP的什么、为什么和如何超出了这个答案的范围,但这就是我可能会做的事情。

编辑:如果你有兴趣的话,这里有一个Spring AOP的链接可以帮助你入门。这是Iive在java中遇到的最容易访问的AOP实现。

另外,考虑到其他人的简单建议,我应该补充一点:AOP适用于不希望时间之类的东西侵入代码的情况。但在很多情况下,这种简单易行的方法是可以的。

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

long startTime = System.currentTimeMillis();

doReallyLongThing();

long endTime = System.currentTimeMillis();

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

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

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

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()));
    }

}