如何获得方法的执行时间? 是否有Timer实用程序类来计时任务所需的时间等?
在谷歌上的大多数搜索都返回调度线程和任务的计时器的结果,这不是我想要的。
如何获得方法的执行时间? 是否有Timer实用程序类来计时任务所需的时间等?
在谷歌上的大多数搜索都返回调度线程和任务的计时器的结果,这不是我想要的。
当前回答
我基本上做的是这种方法的变体,但是考虑到热点编译的工作方式,如果您想要获得准确的结果,您需要抛弃前几个度量,并确保您在真实世界(阅读特定于应用程序的)应用程序中使用该方法。
如果JIT决定编译它,您的数字将会有很大的变化。所以要注意
其他回答
在我的机器上进行性能测量
System.nanoTime(): 750ns System.currentTimeMillis(): 18ns
如前所述,System.nanoTime()被认为是度量经过的时间。只要注意在循环中使用的代价就可以了。
这里有很多有效的答案,它们都是在方法中实现的。为了制作一个通用的计时方法,我通常有一个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();
纯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;
}
}
在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。
非常好的代码。
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;
}