您如何安排Java程序的执行时间?我不确定应该使用哪个类来执行此操作。
我正在寻找类似的东西:
// Some timer starts here
for (int i = 0; i < length; i++) {
// Do something
}
// End timer here
System.out.println("Total execution time: " + totalExecutionTime);
Answers:
final long startTime = System.currentTimeMillis();
for (int i = 0; i < length; i++) {
// Do something
}
final long endTime = System.currentTimeMillis();
System.out.println("Total execution time: " + (endTime - startTime));
final具有您不会意外分配给它的优点(以及其他优点,例如匿名类访问等)。在这段代码中,它没有任何区别。制作所有内容final并仅在final需要时将其统一是一种相当普遍的做法。
请注意,存在一些问题,System#nanoTime()无法可靠地在多核CPU上使用它来记录经过的时间...每个核都有自己的TSC(时间戳计数器):该计数器用于获取纳秒级时间(实际上是自CPU引导以来的滴答数)。
因此,除非操作系统进行一些TSC时间扭曲以保持内核同步,否则如果在获取初始时间读数时线程在一个内核上进行了调度,然后切换到另一个内核,则相对时间可能会偶尔出现向后跳和转发。
我前一段时间在AMD / Solaris上观察到这一点,其中两个时间点之间的经过时间有时以负值或意外大的正数返回。强制使用AMD PowerNow!需要一个Solaris内核补丁和一个BIOS设置。关闭,这似乎解决了它。
此外,System#nanoTime()在VirtualBox环境中使用Java时,还存在(AFAIK)迄今为止尚未修复的错误;由于大多数java.util.concurrency程序包都依赖于nano时间,因此给我们造成了各种奇怪的间歇线程问题。
也可以看看:
System.nanoTime()完全没用吗? http://vbox.innotek.de/pipermail/vbox-trac/2010-January/135631.html
您可以利用System#nanoTime()。在执行之前和之后获取它,然后做一下数学运算即可。上面System#currentTimeMillis()是首选,因为它具有更好的精度。视所使用的硬件和平台而定,否则,您可能会花费不正确的时间间隔。在Windows上使用Core2Duo时,大约在0到15ms之间,实际上什么也无法计算。
一个更高级的工具是探查器。
nanoTime()有一个问题(至少在Windows上);时间戳特定于处理器内核。我有一个程序的执行时间为负数,因为它在一个内核上具有“开始”时间戳,而在另一个内核上具有“停止”时间戳。
使用AOP / AspectJ和@Loggable来自jcabi-aspects的注释,您可以轻松而紧凑地完成它:
@Loggable(Loggable.DEBUG)
public String getSomeResult() {
// return some value
}
对该方法的每次调用都将被发送到具有DEBUG日志记录级别的SLF4J日志记录设备。并且每个日志消息都将包含执行时间。
以下是一些在Java中查找执行时间的方法:
1)System.nanoTime()
long startTime = System.nanoTime();
.....your code....
long endTime = System.nanoTime();
long totalTime = endTime - startTime;
System.out.println("Execution time in nanoseconds : " + totalTime);
System.out.println("Execution time in milliseconds : " + totalTime / 1000000);
2)System.currentTimeMillis()
long startTime = System.currentTimeMillis();
.....your code....
long endTime = System.currentTimeMillis();
long totalTime = endTime - startTime;
System.out.println("Execution time in milliseconds : " + totalTime);
3)Instant.now()
long startTime = Instant.now().toEpochMilli();
.....your code....
long endTime = Instant.now().toEpochMilli();
long totalTime = endTime - startTime;
System.out.println("Execution time in milliseconds: " + totalTime);
要么
Instant start = Instant.now();
.....your code....
Instant end = Instant.now();
Duration interval = Duration.between(start, end);
System.out.println("Execution time in seconds: " +interval.getSeconds());
4)Date.getTime()
long startTime = new Date().getTime();
.....your code....
long endTime = new Date().getTime();
long totalTime = endTime - startTime;
System.out.println("Execution time in milliseconds: " + totalTime);
我创建了一个更高阶的函数,该函数接受您要在/作为lambda度量的代码:
class Utils {
public static <T> T timeIt(String msg, Supplier<T> s) {
long startTime = System.nanoTime();
T t = s.get();
long endTime = System.nanoTime();
System.out.println(msg + ": " + (endTime - startTime) + " ns");
return t;
}
public static void timeIt(String msg, Runnable r) {
timeIt(msg, () -> {r.run(); return null; });
}
}
这样称呼它:
Utils.timeIt("code 0", () ->
System.out.println("Hallo")
);
// in case you need the result of the lambda
int i = Utils.timeIt("code 1", () ->
5 * 5
);
输出:
代码0:180528 ns
代码1:12003 ns
特别感谢Andy Turner帮助我减少了冗余。看这里。
您也可以尝试Perf4J。它是您要寻找的东西的一种整洁的方式,并且可以帮助您在设定的时间范围内汇总性能统计数据,例如平均值,最小值,最大值,标准差和每秒的事务数。来自http://perf4j.codehaus.org/devguide.html的摘录:
StopWatch stopWatch = new LoggingStopWatch();
try {
// the code block being timed - this is just a dummy example
long sleepTime = (long)(Math.random() * 1000L);
Thread.sleep(sleepTime);
if (sleepTime > 500L) {
throw new Exception("Throwing exception");
}
stopWatch.stop("codeBlock2.success", "Sleep time was < 500 ms");
} catch (Exception e) {
stopWatch.stop("codeBlock2.failure", "Exception was: " + e);
}
输出:
INFO: start[1230493236109] time[447] tag[codeBlock2.success] message[Sleep time was < 500 ms]
INFO: start[1230493236719] time[567] tag[codeBlock2.failure] message[Exception was: java.lang.Exception: Throwing exception]
INFO: start[1230493237286] time[986] tag[codeBlock2.failure] message[Exception was: java.lang.Exception: Throwing exception]
INFO: start[1230493238273] time[194] tag[codeBlock2.success] message[Sleep time was < 500 ms]
INFO: start[1230493238467] time[463] tag[codeBlock2.success] message[Sleep time was < 500 ms]
INFO: start[1230493238930] time[310] tag[codeBlock2.success] message[Sleep time was < 500 ms]
INFO: start[1230493239241] time[610] tag[codeBlock2.failure] message[Exception was: java.lang.Exception: Throwing exception]
INFO: start[1230493239852] time[84] tag[codeBlock2.success] message[Sleep time was < 500 ms]
INFO: start[1230493239937] time[30] tag[codeBlock2.success] message[Sleep time was < 500 ms]
INFO: start[1230493239968] time[852] tag[codeBlock2.failure] message[Exception was: java.lang.Exception: Throwing exception]
public class someClass
{
public static void main(String[] args) // your app start point
{
long start = java.util.Calendar.getInstance().getTimeInMillis();
... your stuff ...
long end = java.util.Calendar.getInstance().getTimeInMillis();
System.out.println("it took this long to complete this stuff: " + (end - start) + "ms");
}
}