我的java代码执行了大量查询。对于每个查询,我需要监视执行时间。而且,我还需要监视某些功能的执行时间。那么,有没有办法以优雅的方式做到这一点?
答案 0 :(得分:2)
有一个开源项目可以做到这一点。这是一个示例代码片段。
private final static int BASIC_STOPWATCH_ID =
Audits.mapAudit("example.basicStopwatch");
public void tryOut(){
final Stopwatch stopwatch = Audits.getBasicStopwatch(BASIC_STOPWATCH_ID);
stopwatch.start();
doSomeWork();
stopwatch.stop();
}
Caudit在github上。
答案 1 :(得分:2)
Perf4J是最好的解决方案。
Perf4J是一个开源工具集,用于添加Java服务器端代码定时语句以及记录,分析和监视结果。对于那些熟悉日志框架(如log4j或java.util.logging)的开发人员来说,类比有助于描述Perf4J:
Perf4J是指log4j到的System.currentTimeMillis() 的System.out.println()
如需进一步参考,请访问http://www.infoq.com/articles/perf4j
答案 2 :(得分:0)
如果要测量方法的执行时间,还可以使用Java的System.nanoTime()
方法。它使用您平台上可用的最高分辨率计时器。时间是相对“自由运行时间”,只能与其他nanoTime值进行比较。 (https://blogs.oracle.com/dholmes/entry/inside_the_hotspot_vm_clocks)
然而,记住Java需要很长时间来“热身”是非常重要的。 Java在JVM(Java虚拟机)中运行其编译的字节码,并使用其JIT(即时编译器)在运行时优化部分字节码,以提高性能。
如果您想要准确测量执行速度,您应该多次运行您的功能,并且不要使用第一次运行的测量时间。以下面的代码为例:
import java.util.Random;
import tools.Helpers;
public class DivideInlineShort {
public static void main(String[] args) {
int n = args.length > 0 ? Integer.parseInt(args[0]) : 10000;
Random r = new Random();
for (int i = 0; i < 50; i++)
runTest(n, r.nextInt(8) + 1); // you need the random to prevent the JVM removing the loops
}
public static void runTest(int n, int ran) {
int counter = 0;
long timeStart = System.nanoTime();
for (int j = 0; j < n; j++)
for (int i = ran; i < 100000 + ran; i++)
counter += return1(i);
long timeEnd = System.nanoTime();
System.out.println(
Helpers.roundedTimeInMillis(timeStart, timeEnd) + "\t\t" + counter);
}
public static int return1(int i) {
return i / i;
}
}
前2到3次跑我的机器约700ms,而其余47次约370ms。 这可以解释,因为如果我没记错的话,在一个方法被调用超过10.000次之后内联优化会启动。
因此,如果您想要准确测量代码的执行时间,则应该在同一个JVM实例上多次运行它,而忽略前几轮。