测量Java方法的执行时间

时间:2010-08-01 17:13:07

标签: java

如何计算在Java中执行方法所需的时间?

8 个答案:

答案 0 :(得分:218)

您可以在之前和之后拍摄时间戳快照,然后多次重复实验以平均结果。还有一些可以为您执行此操作的分析器。


来自“Java平台性能:策略与策略”一书:

使用System.currentTimeMillis()

class TimeTest1 {
   public static void main(String[] args) {

      long startTime = System.currentTimeMillis();

      long total = 0;
      for (int i = 0; i < 10000000; i++) {
         total += i;
      }

      long stopTime = System.currentTimeMillis();
      long elapsedTime = stopTime - startTime;
      System.out.println(elapsedTime);
   }
}

使用StopWatch类

您可以使用此StopWatch课程,并在该方法之前和之后致电start()stop

class TimeTest2 {
   public static void main(String[] args) {

      Stopwatch timer = new Stopwatch().start();

      long total = 0;
      for (int i = 0; i < 10000000; i++) {
         total += i;
      }

      timer.stop();
      System.out.println(timer.getElapsedTime());
   }
}

请参阅here


NetBeans Profiler:

  

应用程序性能应用程序

     

性能配置文件方法级CPU   性能(执行时间)。您可以   选择描述整个   申请或部分   应用

请参阅here

答案 1 :(得分:205)

更准确地说,我会使用nanoTime()方法而不是currentTimeMillis()

long startTime = System.nanoTime();
myCall(); 
long stopTime = System.nanoTime();
System.out.println(stopTime - startTime);

在Java 8中(输出格式为ISO-8601):

Instant start = Instant.now();
Thread.sleep(63553);
Instant end = Instant.now();
System.out.println(Duration.between(start, end)); // prints PT1M3.553S

番石榴Stopwatch

Stopwatch stopwatch = Stopwatch.createStarted();
myCall();
stopwatch.stop(); // optional
System.out.println("Time elapsed for myCall() is "+ stopwatch.elapsed(MILLISECONDS));

答案 2 :(得分:36)

请检查:System.currentTimeMillis

通过此操作,您可以通过以下方式计算方法的时间:

long start = System.currentTimeMillis();
class.method();
long time = System.currentTimeMillis() - start;

答案 3 :(得分:31)

如果您为 Android 开发应用程序,则应该试用TimingLogger课程。
看看这些描述TimingLogger帮助程序类的用法的文章:

答案 4 :(得分:12)

您可能想要考虑面向方面的编程。你不想在时间上乱丢你的代码。您希望能够以声明方式关闭它们。

如果您使用Spring,请查看他们的MethodInterceptor课程。

答案 5 :(得分:8)

如果您目前正在编写该应用程序,那么答案是使用System.currentTimeMillisSystem.nanoTime服务于上述人员指出的目的。

但是如果您已经编写了代码,并且您不想更改它,那么最好使用Spring的方法拦截器。例如,您的服务是:

public class MyService { 
    public void doSomething() {
        for (int i = 1; i < 10000; i++) {
            System.out.println("i=" + i);
        }
    }
}

为避免更改服务,您可以编写自己的方法拦截器:

public class ServiceMethodInterceptor implements MethodInterceptor {
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        long startTime = System.currentTimeMillis();
        Object result = methodInvocation.proceed();
        long duration = System.currentTimeMillis() - startTime;
        Method method = methodInvocation.getMethod();
        String methodName = method.getDeclaringClass().getName() + "." + method.getName();
        System.out.println("Method '" + methodName + "' took " + duration + " milliseconds to run");
        return null;
    }
}

还有可用于Java的开源API,例如BTrace。 或者@bakkal和@Saikikos建议的Netbeans剖析器。 感谢。

答案 6 :(得分:5)

建议的nanoTime()在短时间尺度上非常精确。 当需要这种精度时,你需要注意你真正测量的东西。 特别是不测量纳米级电话本身

long start1 = System.nanoTime();
// maybe add here a call to a return to remove call up time, too.
// Avoid optimization 
long start2 = System.nanoTime();
myCall(); 
long stop = System.nanoTime();
long diff = stop - 2*start2 + start1;

System.out.println(diff + " ns");

顺便说一下,由于

,您将为同一个呼叫测量不同的值
  • 计算机上的其他负载(后台,网络,鼠标移动,中断,任务切换,线程)
  • 缓存填充(冷,暖)
  • jit编译(没有优化,由于运行编译器而导致性能下降,由于编译器导致性能提升(但有时使用jit的代码比不使用代码更慢!)。

答案 7 :(得分:1)

Nanotime实际上对于经过的时间来说甚至都没有好处,因为它比currentTimeMillis显着地漂移得更多。此外,纳米级倾向于以牺牲精度为代价提供过高的精度。因此它非常不一致,需要改进。

对于任何时间测量过程,currentTimeMillis(尽管几乎一样糟糕)在平衡精度和精度方面做得更好。