首页 文章

测量Java方法的执行时间[重复]

提问于
浏览
223

这个问题在这里已有答案:

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

8 回答

  • 8

    检查一下:System.currentTimeMillis .

    有了这个,您可以通过以下方式计算方法的时间:

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

    更确切地说,我会使用 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
    

    Guava Stopwatch

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

    如果您当前正在编写应用程序,那么答案是使用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剖析器 . 谢谢 .

  • 35

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

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

  • 29

    您可以在之前和之后获取时间戳快照,然后是 repeat the experiments several times to average to results . 还有可以为您执行此操作的分析器 .


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

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

    With a StopWatch class

    您可以使用此 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 .

  • 11

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

  • 1

    正如所提出的,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的代码比没有编译时慢!))

  • 3

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

    如果您使用Spring,请查看他们的MethodInterceptor类 .

相关问题