【问题标题】:How can I count the time it takes a function to complete in Java?如何计算在 Java 中完成一个函数所需的时间?
【发布时间】:2010-10-16 02:35:10
【问题描述】:

我需要测量一个函数在 Java 中完成所需的时间。我该怎么做?

注意:

我想测量函数的时间消耗,而不是整个程序的时间消耗。

【问题讨论】:

    标签: java profiling


    【解决方案1】:
    long start = System.nanoTime();    
    methodToBeTimed();
    long elapsedTime = System.nanoTime() - start;
    

    【讨论】:

    • 请注意,nanoTime 轮询的时钟可能不精确到 nanoSecond。如果幸运的话,准确度将是 CPU 的时钟速度,否则会是它的几倍。
    • 如果您需要以纳秒为单位对函数进行计时,也许它已经足够快了?将所有内容除以 1 0 亿 看看它是多少秒,这让我很恼火。
    • 我做了这个,精度比使用计时器更精确(在 methodToBeTimed() 之前启动计时器并在 methodToBeTimed 之后停止)
    【解决方案2】:

    这是计算经过时间的方法。

    // Get current time
    long start = System.currentTimeMillis();
    
    // Do something ...
    
    // Get elapsed time in milliseconds
    long elapsedTimeMillis = System.currentTimeMillis()-start;
    
    // Get elapsed time in seconds
    float elapsedTimeSec = elapsedTimeMillis/1000F;
    
    // Get elapsed time in minutes
    float elapsedTimeMin = elapsedTimeMillis/(60*1000F);
    
    // Get elapsed time in hours
    float elapsedTimeHour = elapsedTimeMillis/(60*60*1000F);
    
    // Get elapsed time in days
    float elapsedTimeDay = elapsedTimeMillis/(24*60*60*1000F);
    

    【讨论】:

    • 但是这个很有用,很艰难。 :D
    【解决方案3】:

    如果您使用 Guava,请考虑使用 Stopwatch,例如:

    final Stopwatch sw = Stopwatch.createStarted();
    methodToBeTimed();
    final long elapsedMillis = sw.elapsed(TimeUnit.MILLISECONDS);
    

    【讨论】:

      【解决方案4】:

      【讨论】:

      • 矫枉过正..但我想说同样的话:-)
      【解决方案5】:

      如果您有多个功能,探查器是正确的答案。

      到目前为止,我看到的所有建议的另一个问题是它们对于单个函数工作正常,但是您的代码将充满您无法关闭的计时内容。

      如果您知道如何进行面向方面的编程,那么将时序代码保存在一个地方并以声明方式应用它是一种好方法。如果您使用 Log4J 之类的东西来输出值,您可以选择关闭或打开它。这是一个穷人的剖析器。

      看看 AspectJ 或 Spring 的 AOP。

      【讨论】:

      • 我同意,如果您只想计时 one 函数,那么探查器就大材小用了;但是,即使您一开始只想为一个功能计时,通常最终会计时更多。
      【解决方案6】:

      上面的所有代码 sn-ps 测量从调用方法到方法返回/抛出异常的时间的大致时间。此类技术无法解决线程调度、GC 引起的暂停等问题。

      是的,一些分析器会做合理的工作。

      如果您使用 Java 1.6 及更高版本,则可以使用基于 JMX 的 VM 管理和监控支持。例如,您可能会发现ThreadMXBean.getCurrentThreadCpuTime() 的价值。在方法调用之前和之后计算这个值的差异会给你:

      "...当前线程的总CPU时间,以纳秒为单位。返回值是纳秒精度,但不一定是纳秒精度。如果实现区分用户模式时间和系统模式时间,则返回的CPU时间是当前线程在用户模式或系统模式下执行的时间量。”

      如果您的方法产生工作线程,那么您的计算将需要更加精细;-)

      一般来说,我建议在 java.lang.mangement 包周围寻找。

      【讨论】:

        【解决方案7】:

        System.nanoTime 应该用于精确测量两次微基准测试之间的增量。

        public class CountTime {
        
          private static void walk() {
            for (int i = 0; i < Integer.MAX_VALUE; i++)
              ;
          }
        
          public static void main(String[] args) {
            long t0 = System.nanoTime();
            walk();
            long t1 = System.nanoTime();
            System.out.println("Elapsed time =" + (t1 - t0)
                + " nanoseconds");
          }
        
        }
        

        System.currentTimeMillis 以毫秒为单位返回当前时间。您可以使用它来获取当前时间。这对于较旧的 VM 或运行时间较长的进程可能很有用。

        【讨论】:

          【解决方案8】:

          使用 System.currentTimeMillis() 或 System.nanoTime():

          int someMethod() {
              long tm = System.nanoTime();
              try {
                  ...
              } finally {
                  tm = System.nanoTime()-tm;
                  System.out.println("time spent in someMethod(): " + tm + "ns");
              }
          }
          

          【讨论】:

            【解决方案9】:

            这款模拟秒表也是我们的另一种选择...... 检查Java2s.com here.

            【讨论】:

              【解决方案10】:

              如果要获取当前时间,请使用java.util.Date

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多