度量Java方法的执行时间

如何计算在Java中执行一个方法所花费的时间?

565705 次浏览

检查这个:System.currentTimeMillis

你可以这样计算你的方法的时间:

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

你可以在重复实验几次以求平均结果之前和之后拍摄时间戳快照。也有一些剖析器可以帮你做到这一点。


摘自《Java平台性能:策略与策略》;书:

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());
}
}

参见在这里(已存档)。


NetBeans分析器:

应用性能应用

性能概要方法级CPU 性能(执行时间)。你可以 选择配置整个 应用程序的一部分 应用程序。< / p >

看到在这里

更准确地说,我将使用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.createStarted();
myCall();
stopwatch.stop(); // optional
System.out.println("Time elapsed: "+ stopwatch.elapsed(TimeUnit.MILLISECONDS));

您可能需要考虑面向方面的编程。你不希望你的代码中充斥着时间。您希望能够以声明的方式关闭和打开它们。

如果你使用Spring,看看他们的MethodInterceptor类。

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的代码比不使用Jit的代码慢!))

如果你目前正在编写应用程序,那么答案是使用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 profiler。 谢谢。< / p >

事实上,Nanotime甚至不适用于流逝时间,因为它比currentTimeMillis漂移得更厉害。此外,纳米时间往往以牺牲准确性为代价来提供过高的精度。因此,它是高度不一致的,需要改进。

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

如果你为安卓开发应用程序,你应该尝试TimingLogger类 看看这些描述TimingLogger帮助类用法的文章