如何获得方法的执行时间? 是否有Timer实用程序类来计时任务所需的时间等?

在谷歌上的大多数搜索都返回调度线程和任务的计时器的结果,这不是我想要的。


当前回答

在Java 8中,你也可以对每个正常的方法做这样的事情:

Object returnValue = TimeIt.printTime(() -> methodeWithReturnValue());
//do stuff with your returnValue

与TimeIt像:

public class TimeIt {

public static <T> T printTime(Callable<T> task) {
    T call = null;
    try {
        long startTime = System.currentTimeMillis();
        call = task.call();
        System.out.print((System.currentTimeMillis() - startTime) / 1000d + "s");
    } catch (Exception e) {
        //...
    }
    return call;
}
}

使用这种方法,您可以在代码的任何地方进行简单的时间测量,而不会破坏它。在这个简单的例子中,我只是打印时间。你可以为TimeIt添加一个开关,例如,在DebugMode中只打印时间。

如果你正在使用函数,你可以这样做:

Function<Integer, Integer> yourFunction= (n) -> {
        return IntStream.range(0, n).reduce(0, (a, b) -> a + b);
    };

Integer returnValue = TimeIt.printTime2(yourFunction).apply(10000);
//do stuff with your returnValue

public static <T, R> Function<T, R> printTime2(Function<T, R> task) {
    return (t) -> {
        long startTime = System.currentTimeMillis();
        R apply = task.apply(t);
        System.out.print((System.currentTimeMillis() - startTime) / 1000d
                + "s");
        return apply;
    };
}

其他回答

为此,我们使用了AspectJ和Java注释。如果我们需要知道一个方法的执行时间,我们可以简单地注释它。更高级的版本可以使用自己的日志级别,可以在运行时启用和禁用。

public @interface Trace {
  boolean showParameters();
}

@Aspect
public class TraceAspect {
  [...]
  @Around("tracePointcut() && @annotation(trace) && !within(TraceAspect)")
  public Object traceAdvice ( ProceedingJintPoint jP, Trace trace ) {

    Object result;
    // initilize timer

    try { 
      result = jp.procced();
    } finally { 
      // calculate execution time 
    }

    return result;
  }
  [...]
}

我基本上做的是这种方法的变体,但是考虑到热点编译的工作方式,如果您想要获得准确的结果,您需要抛弃前几个度量,并确保您在真实世界(阅读特定于应用程序的)应用程序中使用该方法。

如果JIT决定编译它,您的数字将会有很大的变化。所以要注意

long startTime = System.currentTimeMillis();
// code goes here
long finishTime = System.currentTimeMillis();
long elapsedTime = finishTime - startTime; // elapsed time in milliseconds

这可能不是您想让我说的,但是这是AOP的一个很好的用法。在您的方法周围使用代理拦截器,并在其中进行计时。

遗憾的是,AOP的什么、为什么和如何超出了这个答案的范围,但这就是我可能会做的事情。

编辑:如果你有兴趣的话,这里有一个Spring AOP的链接可以帮助你入门。这是Iive在java中遇到的最容易访问的AOP实现。

另外,考虑到其他人的简单建议,我应该补充一点:AOP适用于不希望时间之类的东西侵入代码的情况。但在很多情况下,这种简单易行的方法是可以的。

我修改了代码,从正确答案得到的结果在几秒钟内:

long startTime = System.nanoTime();

methodCode ...

long endTime = System.nanoTime();
double duration = (double)(endTime - startTime) / (Math.pow(10, 9));
Log.v(TAG, "MethodName time (s) = " + duration);