测量Java方法的执行时间
如何计算在Java中执行方法所用的时间?
您可以在拍摄之前和之后拍摄时间戳快照,然后重复实验数次以平均得出结果 。 也有configuration文件可以为你做这个。
从“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()); } }
看到这里 。
NetBeans Profiler:
应用性能应用
性能configuration文件方法级别的CPU性能(执行时间) 。 您可以select分析整个应用程序或部分应用程序。
看到这里 。
更确切地说,我会使用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 for myCall() is "+ stopwatch.elapsed(MILLISECONDS));
选中这个: System.currentTimeMillis 。
有了这个,你可以计算出你的方法的时间:
long start = System.currentTimeMillis(); class.method(); long time = System.currentTimeMillis() - start;
如果您为Android开发应用程序,则应该尝试使用TimingLogger
类。
看看这些描述TimingLogger
助手类用法的文章:
- 测量Android SDK中的性能 (27.09.2010)
- 发现Android API – 第1部分 (03.01.2017)
您可能想要考虑面向方面的编程。 你不想乱丢你的代码。 你想能够把它们closures和声明。
如果你使用Spring,看一下他们的MethodInterceptor类。
如果你正在编写这个应用程序,答案就是使用System.currentTimeMillis或System.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 。 或Netbeans分析器如@ bakkal和@Saikikos所build议的那样。 谢谢。
正如所提出的,nanoTime()在短时间尺度上非常精确。 当需要这个精度时,你需要关心你真正衡量的东西。 尤其不要测量碳纳米pipe本身
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");
顺便说一句,你会测量不同的值,因为同一个电话
- 您计算机上的其他负载(背景,networking,鼠标移动,中断,任务切换,线程)
- caching填充(冷,暖)
- jit编译(没有优化,由于运行编译器而导致性能降低,编译器性能提高(但是有时jit编码比没有编译时慢))
实际上Nanotime在时间上并不算好,因为它远远超过currentTimeMillis。 此外,以牺牲准确性为代价,纳米级往往会提供过高的精度。 因此高度不一致,需要细化。
对于任何时间的测量过程,currentTimeMillis(虽然几乎一样糟糕),在平衡准确性和精度方面做的更好。