如何获得方法的执行时间? 是否有Timer实用程序类来计时任务所需的时间等?
在谷歌上的大多数搜索都返回调度线程和任务的计时器的结果,这不是我想要的。
如何获得方法的执行时间? 是否有Timer实用程序类来计时任务所需的时间等?
在谷歌上的大多数搜索都返回调度线程和任务的计时器的结果,这不是我想要的。
当前回答
纯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;
}
}
其他回答
使用分析器(JProfiler, Netbeans profiler, Visual VM, Eclipse profiler等)。您将得到最准确的结果,并且是最少的干扰。它们使用内置的JVM机制进行概要分析,还可以为您提供额外的信息,如堆栈跟踪、执行路径以及必要时更全面的结果。
当使用完全集成的分析器时,对方法进行分析是非常简单的。右击,分析器->添加到根方法。然后像运行测试运行或调试器一样运行剖析器。
对于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;
}
也可以实现定时器接口,并在类的任何方法上执行
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);
加油,伙计们!没有人提到用番石榴来做这件事(可以说是很棒):
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+
纯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;
}
}