如何获得方法的执行时间? 是否有Timer实用程序类来计时任务所需的时间等?
在谷歌上的大多数搜索都返回调度线程和任务的计时器的结果,这不是我想要的。
如何获得方法的执行时间? 是否有Timer实用程序类来计时任务所需的时间等?
在谷歌上的大多数搜索都返回调度线程和任务的计时器的结果,这不是我想要的。
当前回答
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()));
}
}
其他回答
如果您不使用工具,并且希望对执行时间较短的方法进行计时,那么只需执行多次,每次将执行次数增加一倍,直到达到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编译器完成它的工作,然后重复此测试多次,并使用最短的执行时间。
这里有很多有效的答案,它们都是在方法中实现的。为了制作一个通用的计时方法,我通常有一个timing类,它由以下内容组成。
public record TimedResult<T>(T result, Duration duration) {}
public static Duration time(Runnable r) {
var s = Instant.now();
r.run();
var dur = Duration.between(s, Instant.now());
return dur;
}
public static <T> TimedResult<T> time(Callable<T> r) throws Exception {
var s = Instant.now();
T res = r.call();
var dur = Duration.between(s, Instant.now());
return new TimedResult<>(res, dur);
}
这足够通用,可以传递Runnable或Callable对象。
Duration result = Timing.time(() -> {
// do some work.
});
TimedResult<String> result = Timing.time(() -> {
// do some work.
return "answer";
});
Duration timeTaken = result.duration();
String answer = result.result();
也可以实现定时器接口,并在类的任何方法上执行
import java.util.function.*;
public interface Timer {
default void timeIt(Runnable r) {
timeIt(() -> { r.run(); return 0;});
}
default <S,T> T timeIt(Function<S,T> fun, S arg) {
long start = System.nanoTime();
T result = fun.apply(arg);
long stop = System.nanoTime();
System.out.println("Time: " + (stop-start)/1000000.0 + " msec");
return result;
}
default <T> T timeIt(Supplier<T> s) {
return timeIt(obj -> s.get(), null);
}
}
用法:
class MyClass implements Timer ..
timeIt(this::myFunction);
纯Java SE代码,不需要添加依赖项,使用TimeTracedExecuter:
public static void main(String[] args) {
Integer square = new TimeTracedExecutor<>(Main::calculateSquare)
.executeWithInput("calculate square of num",5,logger);
}
public static int calculateSquare(int num){
return num*num;
}
会产生这样的结果:
信息:计算num的平方需要3毫秒
自定义可重用类:TimeTracedExecutor
import java.text.NumberFormat;
import java.time.Duration;
import java.time.Instant;
import java.util.function.Function;
import java.util.logging.Logger;
public class TimeTracedExecutor<T,R> {
Function<T,R> methodToExecute;
public TimeTracedExecutor(Function<T, R> methodToExecute) {
this.methodToExecute = methodToExecute;
}
public R executeWithInput(String taskDescription, T t, Logger logger){
Instant start = Instant.now();
R r= methodToExecute.apply(t);
Instant finish = Instant.now();
String format = "It took %s milliseconds to "+taskDescription;
String elapsedTime = NumberFormat.getNumberInstance().format(Duration.between(start, finish).toMillis());
logger.info(String.format(format, elapsedTime));
return r;
}
}
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;
}
}