时间执行代码可能很方便,因此您知道需要花费多长时间。但是,我发现这样做的普遍做法很草率,因为它应该具有相同的缩进,这使得读取实际计时内容变得更加困难。
long start = System.nanoTime();
// The code you want to time
long end = System.nanoTime();
System.out.printf("That took: %d ms.%n", TimeUnit.NANOSECONDS.toMillis(end - start));
我想出了以下几点,它看起来更好,有一些优点和缺点:
优势:
缺点:
AutoClosable
的方式(很确定)TimeCode
新实例try
块中声明的变量无法在其外部访问可以这样使用:
try (TimeCode t = new TimeCode()) {
// The stuff you want to time
}
使之成为可能的代码是:
class TimeCode implements AutoCloseable {
private long startTime;
public TimeCode() {
this.startTime = System.nanoTime();
}
@Override
public void close() throws Exception {
long endTime = System.nanoTime();
System.out.printf("That took: %d ms%n",
TimeUnit.NANOSECONDS.toMillis(endTime - this.startTime));
}
}
我的问题是:
答案 0 :(得分:3)
您的解决方案就可以了。
一种不太具表现力的方法是将要计时的代码包装在lambda中。
public void timeCode(Runnable code) {
...
try {
code.run();
} catch ...
}
...
}
timeCode(() -> { ...code to time... });
您可能想捕获已检查的异常并将它们传递给某个运行时异常或其他任何东西。
答案 1 :(得分:1)
您的方法原样很棒。我们在专业上使用类似的东西,但是都是用C#编写的。
我可能要添加的一件事是适当的日志记录支持,以便您可以切换这些性能数字,或者将其设置为调试或信息级别。
我要考虑的其他改进是创建一些静态应用程序状态(滥用线程局部变量),以便您可以嵌套这些部分并进行摘要。
请参见https://github.com/aikar/minecraft-timings,了解用于Minecraft改装(用Java编写)的库。
答案 2 :(得分:1)
我认为问题文本中建议的解决方案是太间接和非惯用语以至于不适合生产代码。 (但是,它看起来像是一种精巧的工具,可以在开发过程中快速地进行工作安排。)
Guava project和Apache Commons都包含秒表类。如果您使用它们中的任何一个,代码将更易于阅读和理解,并且这些类也具有更多的内置功能。</ p>
即使不使用try-with-resource语句,也可以将要测量的部分封闭在一个块中,以提高清晰度:
// Do things that shouldn't be measured
{
Stopwatch watch = Stopwatch.createStarted();
// Do things that should be measured
System.out.println("Duration: " + watch.elapsed(TimeUnit.SECONDS) + " s");
}
答案 3 :(得分:-1)
写下每个方面,而不是每次都调用性能方法。
@Pointcut("(execution(* com.resources.delegate.*.*(..)) "
+ "|| execution(* com.resources.implementation.*.*(..))) ")
public void resourceLayerPointCut() {
}
@Pointcut("(execution(* com.models.delegate.*.*(..)) "
+ "|| execution(* com.repo.implementation.*.*(..))) ")
public void exclusionsPointcut() {
}
周围是您的方法上写的建议,它将同时打印开始时间和结束时间。您不必每次都调用它。
@Around(value = "resourceLayerPointCut() && exclusionsPointcut()")
public Object aroundResourceLayerMethods(ProceedingJoinPoint code) throws Throwable {
long startTime = System.currentTimeMillis();
Object returnValue = null;
try {
//This will call your methods
returnValue = code.proceed();
} catch (Throwable e) {
log(joinPoint, startTime, returnValue, Layer.ResourceLayer, true);
throw (e);
}
long endTime = System.currentTimeMillis();
System.out.printf("That took: %d ms%n", endTime - this.startTime);
return returnValue;
}