如何获得方法的执行时间? 是否有Timer实用程序类来计时任务所需的时间等?
在谷歌上的大多数搜索都返回调度线程和任务的计时器的结果,这不是我想要的。
如何获得方法的执行时间? 是否有Timer实用程序类来计时任务所需的时间等?
在谷歌上的大多数搜索都返回调度线程和任务的计时器的结果,这不是我想要的。
当前回答
nanotime()是一个非常精确的系统实用程序,用于测量执行时间。但是要注意,如果运行在抢占式调度器模式(默认),这个实用程序实际上测量的是时钟时间,而不是CPU时间。因此,您可能会注意到每次运行的执行时间值是不同的,这取决于系统负载。如果您需要CPU时间,我认为在实时模式下运行您的程序就可以了。您必须使用RT linux。链接:使用Linux进行实时编程
其他回答
如果您不使用工具,并且希望对执行时间较短的方法进行计时,那么只需执行多次,每次将执行次数增加一倍,直到达到1秒左右。因此,系统调用的时间。纳米时间等,也没有系统的准确性。nanoTime确实对结果有很大影响。
int runs = 0, runsPerRound = 10;
long begin = System.nanoTime(), end;
do {
for (int i=0; i<runsPerRound; ++i) timedMethod();
end = System.nanoTime();
runs += runsPerRound;
runsPerRound *= 2;
} while (runs < Integer.MAX_VALUE / 2 && 1000000000L > end - begin);
System.out.println("Time for timedMethod() is " +
0.000000001 * (end-begin) / runs + " seconds");
当然,使用挂钟也有一些注意事项:jit编译、多线程/进程等的影响。因此,您需要首先执行该方法很多次,以便JIT编译器完成它的工作,然后重复此测试多次,并使用最短的执行时间。
这可能不是您想让我说的,但是这是AOP的一个很好的用法。在您的方法周围使用代理拦截器,并在其中进行计时。
遗憾的是,AOP的什么、为什么和如何超出了这个答案的范围,但这就是我可能会做的事情。
编辑:如果你有兴趣的话,这里有一个Spring AOP的链接可以帮助你入门。这是Iive在java中遇到的最容易访问的AOP实现。
另外,考虑到其他人的简单建议,我应该补充一点:AOP适用于不希望时间之类的东西侵入代码的情况。但在很多情况下,这种简单易行的方法是可以的。
非常好的代码。
http://www.rgagnon.com/javadetails/java-0585.html
import java.util.concurrent.TimeUnit;
long startTime = System.currentTimeMillis();
........
........
........
long finishTime = System.currentTimeMillis();
String diff = millisToShortDHMS(finishTime - startTime);
/**
* converts time (in milliseconds) to human-readable format
* "<dd:>hh:mm:ss"
*/
public static String millisToShortDHMS(long duration) {
String res = "";
long days = TimeUnit.MILLISECONDS.toDays(duration);
long hours = TimeUnit.MILLISECONDS.toHours(duration)
- TimeUnit.DAYS.toHours(TimeUnit.MILLISECONDS.toDays(duration));
long minutes = TimeUnit.MILLISECONDS.toMinutes(duration)
- TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(duration));
long seconds = TimeUnit.MILLISECONDS.toSeconds(duration)
- TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(duration));
if (days == 0) {
res = String.format("%02d:%02d:%02d", hours, minutes, seconds);
}
else {
res = String.format("%dd%02d:%02d:%02d", days, hours, minutes, seconds);
}
return res;
}
对于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;
}
我的答案很简单。对我有用。
long startTime = System.currentTimeMillis();
doReallyLongThing();
long endTime = System.currentTimeMillis();
System.out.println("That took " + (endTime - startTime) + " milliseconds");
它运行得很好。分辨率显然只有毫秒级,使用System.nanoTime()可以做得更好。这两种方法都有一些限制(操作系统调度切片等),但效果很好。
平均几次运行(越多越好),你就会得到一个不错的想法。