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

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


当前回答

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

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

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

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

其他回答

加油,伙计们!没有人提到用番石榴来做这件事(可以说是很棒):

import com.google.common.base.Stopwatch;

Stopwatch timer = Stopwatch.createStarted();
//method invocation
LOG.info("Method took: " + timer.stop());

Stopwatch.toString()很好地为测量选择了时间单位。也就是说,如果值很小,它将输出38ns,如果值很长,它将显示5m 3s

甚至更好的:

Stopwatch timer = Stopwatch.createUnstarted();
for (...) {
   timer.start();
   methodToTrackTimeFor();
   timer.stop();
   methodNotToTrackTimeFor();
}
LOG.info("Method took: " + timer);

注意:谷歌Guava需要Java 1.6+

有几种方法可以做到。我通常会使用这样的方法:

long start = System.currentTimeMillis();
// ... do something ...
long end = System.currentTimeMillis();

或者System.nanoTime();

关于基准测试方面的更多内容,似乎还有这个:http://jetm.void.fm/但从未尝试过。

在Java 8中引入了一个名为Instant的新类。根据文件:

Instant represents the start of a nanosecond on the time line. This class is useful for generating a time stamp to represent machine time. The range of an instant requires the storage of a number larger than a long. To achieve this, the class stores a long representing epoch-seconds and an int representing nanosecond-of-second, which will always be between 0 and 999,999,999. The epoch-seconds are measured from the standard Java epoch of 1970-01-01T00:00:00Z where instants after the epoch have positive values, and earlier instants have negative values. For both the epoch-second and nanosecond parts, a larger value is always later on the time-line than a smaller value.

这可以用于:

Instant start = Instant.now();
try {
    Thread.sleep(7000);
} catch (InterruptedException e) {
    e.printStackTrace();
}
Instant end = Instant.now();
System.out.println(Duration.between(start, end));

打印pt7.001。

在我的机器上进行性能测量

System.nanoTime(): 750ns System.currentTimeMillis(): 18ns

如前所述,System.nanoTime()被认为是度量经过的时间。只要注意在循环中使用的代价就可以了。

如果java有更好的功能支持就好了,这样需要测量的动作就可以被包装到一个块中:

measure {
   // your operation here
}

在java中,这可以通过匿名函数来完成,看起来太冗长了

public interface Timer {
    void wrap();
}


public class Logger {

    public static void logTime(Timer timer) {
        long start = System.currentTimeMillis();
        timer.wrap();
        System.out.println("" + (System.currentTimeMillis() - start) + "ms");
    }

    public static void main(String a[]) {
        Logger.logTime(new Timer() {
            public void wrap() {
                // Your method here
                timeConsumingOperation();
            }
        });

    }

    public static void timeConsumingOperation() {
        for (int i = 0; i<=10000; i++) {
           System.out.println("i=" +i);
        }
    }
}