如何在 Java 中为方法的执行计时?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/180158/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 10:59:14  来源:igfitidea点击:

How do I time a method's execution in Java?

javatimingexecution-time

提问by Ogre Psalm33

  1. How do I get a method's execution time?
  2. Is there a Timerutility class for things like timing how long a task takes, etc?
  1. 如何获得方法的执行时间?
  2. 是否有Timer用于计时任务需要多长时间等的实用程序类?

Most of the searches on Google return results for timers that schedule threads and tasks, which is not what I want.

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

采纳答案by Diastrophism

There is always the old-fashioned way:

总是有老式的方法:

long startTime = System.nanoTime();
methodToTime();
long endTime = System.nanoTime();

long duration = (endTime - startTime);  //divide by 1000000 to get milliseconds.

回答by skaffman

This probably isn't what you wanted me to say, but this is a good use of AOP. Whip an proxy interceptor around your method, and do the timing in there.

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

The what, why and how of AOP is rather beyond the scope of this answer, sadly, but that's how I'd likely do it.

遗憾的是,AOP 的内容、原因和方式超出了这个答案的范围,但这就是我可能会这样做的方式。

Edit: Here's a linkto Spring AOP to get you started, if you're keen. This is the most accessible implementation of AOP that Iive come across for java.

编辑:如果您愿意,这里有一个指向Spring AOP的链接,可以帮助您入门。这是 Iive 在 Java 中遇到的最容易访问的 AOP 实现。

Also, given everyone else's very simple suggestions, I should add that AOP is for when you don't want stuff like timing to invade your code. But in many cases, that sort of simple and easy approach is fine.

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

回答by MBCook

I go with the simple answer. Works for me.

我用简单的答案。为我工作。

long startTime = System.currentTimeMillis();

doReallyLongThing();

long endTime = System.currentTimeMillis();

System.out.println("That took " + (endTime - startTime) + " milliseconds");

It works quite well. The resolution is obviously only to the millisecond, you can do better with System.nanoTime(). There are some limitations to both (operating system schedule slices, etc.) but this works pretty well.

它运作良好。分辨率显然只有到毫秒,你可以用 System.nanoTime() 做的更好。两者都有一些限制(操作系统调度切片等),但效果很好。

Average across a couple of runs (the more the better) and you'll get a decent idea.

几次运行的平均值(越多越好),你会得到一个不错的主意。

回答by David Nehme

If you want wall-clock time

如果你想要挂钟时间

long start_time = System.currentTimeMillis();
object.method();
long end_time = System.currentTimeMillis();
long execution_time = end_time - start_time;

回答by Ryan Rodemoyer

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

回答by luke

I basically do variations of this, but considering how hotspot compilation works, if you want to get accurate results you need to throw out the first few measurements and make sure you are using the method in a real world (read application specific) application.

我基本上做了这种变化,但考虑到热点编译的工作原理,如果您想获得准确的结果,您需要放弃前几次测量并确保您在现实世界(阅读特定于应用程序)应用程序中使用该方法。

If the JIT decides to compile it your numbers will vary heavily. so just be aware

如果 JIT 决定编译它,您的数字将有很大差异。所以请注意

回答by Horst Gutmann

There are a couple of ways to do that. I normally fall back to just using something like this:

有几种方法可以做到这一点。我通常会回退到只使用这样的东西:

long start = System.currentTimeMillis();
// ... do something ...
long end = System.currentTimeMillis();

or the same thing with System.nanoTime();

或与 System.nanoTime() 相同;

For something more on the benchmarking side of things there seems also to be this one: http://jetm.void.fm/Never tried it though.

对于基准测试方面的更多内容,似乎还有这个:http: //jetm.void.fm/虽然从未尝试过。

回答by anjanb

As "skaffman" said, use AOP OR you can use run time bytecode weaving, just like unit test method coverage tools use to transparently add timing info to methods invoked.

正如“skaffman”所说,使用 AOP 或者您可以使用运行时字节码编织,就像单元测试方法覆盖工具用来透明地向调用的方法添加计时信息一样。

You can look at code used by open source tools tools like Emma (http://downloads.sourceforge.net/emma/emma-2.0.5312-src.zip?modtime=1118607545&big_mirror=0). The other opensource coverage tool is http://prdownloads.sourceforge.net/cobertura/cobertura-1.9-src.zip?download.

您可以查看 Emma 等开源工具工具使用的代码(http://downloads.sourceforge.net/emma/emma-2.0.5312-src.zip?modtime=1118607545&big_mirror=0)。另一个开源覆盖工具是http://prdownloads.sourceforge.net/cobertura/cobertura-1.9-src.zip?download

If you eventually manage to do what you set out for, pls. share it back with the community here with your ant task/jars.

如果你最终设法做你设定的,请。在这里与您的 ant 任务/罐子与社区分享它。

回答by James Schek

Use a profiler (JProfiler, Netbeans Profiler, Visual VM, Eclipse Profiler, etc). You'll get the most accurate results and is the least intrusive. They use the built-in JVM mechanism for profiling which can also give you extra information like stack traces, execution paths, and more comprehensive results if necessary.

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

When using a fully integrated profiler, it's faily trivial to profile a method. Right click, Profiler -> Add to Root Methods. Then run the profiler just like you were doing a test run or debugger.

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

回答by James Schek

We are using AspectJ and Java annotations for this purpose. If we need to know to execution time for a method, we simple annotate it. A more advanced version could use an own log level that can enabled and disabled at runtime.

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