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

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


当前回答

使用分析器(JProfiler, Netbeans profiler, Visual VM, Eclipse profiler等)。您将得到最准确的结果,并且是最少的干扰。它们使用内置的JVM机制进行概要分析,还可以为您提供额外的信息,如堆栈跟踪、执行路径以及必要时更全面的结果。

当使用完全集成的分析器时,对方法进行分析是非常简单的。右击,分析器->添加到根方法。然后像运行测试运行或调试器一样运行剖析器。

其他回答

加油,伙计们!没有人提到用番石榴来做这件事(可以说是很棒):

import com.google.common.base.Stopwatch;

Stopwatch timer = Stopwatch.createStarted();
//method invocation
LOG.info("Method took: " + timer.stop());

Stopwatch.toString()很好地为测量选择了时间单位。也就是说,如果值很小,它将输出38ns,如果值很长,它将显示5m 3s

甚至更好的:

Stopwatch timer = Stopwatch.createUnstarted();
for (...) {
   timer.start();
   methodToTrackTimeFor();
   timer.stop();
   methodNotToTrackTimeFor();
}
LOG.info("Method took: " + timer);

注意:谷歌Guava需要Java 1.6+

您可以使用Perf4j。非常酷的实用工具。用法简单

String watchTag = "target.SomeMethod";
StopWatch stopWatch = new LoggingStopWatch(watchTag);
Result result = null; // Result is a type of a return value of a method
try {
    result = target.SomeMethod();
    stopWatch.stop(watchTag + ".success");
} catch (Exception e) {
    stopWatch.stop(watchTag + ".fail", "Exception was " + e);
    throw e; 
}

更多信息可以在开发者指南中找到

编辑:项目似乎已死

这是一个简单的类用于简单的函数计时。下面有一个例子。

public class Stopwatch {
    static long startTime;
    static long splitTime;
    static long endTime;

    public Stopwatch() {
        start();
    }

    public void start() {
        startTime = System.currentTimeMillis();
        splitTime = System.currentTimeMillis();
        endTime = System.currentTimeMillis();
    }

    public void split() {
        split("");
    }

    public void split(String tag) {
        endTime = System.currentTimeMillis();
        System.out.println("Split time for [" + tag + "]: " + (endTime - splitTime) + " ms");
        splitTime = endTime;
    }

    public void end() {
        end("");
    }
    public void end(String tag) {
        endTime = System.currentTimeMillis();
        System.out.println("Final time for [" + tag + "]: " + (endTime - startTime) + " ms");
    }
}

使用示例:

public static Schedule getSchedule(Activity activity_context) {
        String scheduleJson = null;
        Schedule schedule = null;
/*->*/  Stopwatch stopwatch = new Stopwatch();

        InputStream scheduleJsonInputStream = activity_context.getResources().openRawResource(R.raw.skating_times);
/*->*/  stopwatch.split("open raw resource");

        scheduleJson = FileToString.convertStreamToString(scheduleJsonInputStream);
/*->*/  stopwatch.split("file to string");

        schedule = new Gson().fromJson(scheduleJson, Schedule.class);
/*->*/  stopwatch.split("parse Json");
/*->*/  stopwatch.end("Method getSchedule"); 
    return schedule;
}

控制台输出示例:

Split time for [file to string]: 672 ms
Split time for [parse Json]: 893 ms
Final time for [get Schedule]: 1565 ms

为此,我们使用了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;
  }
  [...]
}

在我的机器上进行性能测量

System.nanoTime(): 750ns System.currentTimeMillis(): 18ns

如前所述,System.nanoTime()被认为是度量经过的时间。只要注意在循环中使用的代价就可以了。