Java中有秒表吗?


107

Java中有秒表吗?在Google上,我只找到无法使用的秒表代码-它们总是返回0毫秒。

我发现的这段代码行不通,但我不明白为什么。

public class StopWatch {

  private long startTime = 0;
  private long stopTime = 0;
  private boolean running = false;


  public void start() {
    this.startTime = System.currentTimeMillis();
    this.running = true;
  }


  public void stop() {
    this.stopTime = System.currentTimeMillis();
    this.running = false;
  }


  //elaspsed time in milliseconds
  public long getElapsedTime() {
    long elapsed;
    if (running) {
      elapsed = (System.currentTimeMillis() - startTime);
    } else {
      elapsed = (stopTime - startTime);
    }
    return elapsed;
  }


  //elaspsed time in seconds
  public long getElapsedTimeSecs() {
    long elapsed;
    if (running) {
      elapsed = ((System.currentTimeMillis() - startTime) / 1000);
    } else {
      elapsed = ((stopTime - startTime) / 1000);
    }
    return elapsed;
  }
}

10
您如何确定它不起作用?(也许你测量的东西,花费较少的时间比System.currentTimeMillis的()的精度来执行)

5
请张贴代码如何测试该课程...
DXTR66

2
只是要注意,这是“ Java编程简介,综合版本(第9版)”中的教科书问题之一。
山姆

2
请不要将其currentTimeMillis()用于生产,因为它与系统日期/时间相关,并且不能保证其单调(例如,您可能会获得负的经过时间)。用于测量时间nanoTime()–保证它是单调的,并且专门用于测量目的。见docs.oracle.com/javase/8/docs/api/java/lang/...
尼基塔Bosik

Answers:



90

使用番石榴的Stopwatch课程

测量经过时间的对象(以纳秒为单位)。使用此类而不是直接调用来测量经过时间非常有用 System.nanoTime()出于某些原因,:

  • 出于测试或性能方面的原因,可以替换备用时间源。
  • 如nanoTime所记录,返回的值没有绝对含义,并且只能解释为相对于nanoTime在不同时间返回的另一个时间戳。秒表是一种更有效的抽象方法,因为它仅公开这些相对值,而不公开绝对值。
Stopwatch stopwatch = Stopwatch.createStarted();
doSomething();
stopwatch.stop(); // optional

long millis = stopwatch.elapsed(TimeUnit.MILLISECONDS);

log.info("that took: " + stopwatch); // formatted string like "12.3 ms"

2
guavas秒表不见了getStartTime(),apache也不见了isRunning()
致Kra 2015年

3
@ToKra您将如何处理开始时间?由于是纳米时间,因此您无法将其用于任何有意义的事情,如文档中所述。
Trejkaz

1
现在,您可以使用它来获取毫秒数:long stopWatch = stopWatch.elapsed(TimeUnit.MILLISECONDS);
PHPGuru

它是哪个番石榴版本?我使用1.8,但找不到秒表类
Laser Infinite

58

现在,您可以尝试执行以下操作:

Instant starts = Instant.now();
Thread.sleep(10);
Instant ends = Instant.now();
System.out.println(Duration.between(starts, ends));

输出为ISO 8601。


1
快速简便,非常感谢!从一开始就帮助跟踪任务持续时间。
ndm13'1

如果您在睡眠期间更改系统时间怎么办?
彼得

1
@Peteter仅是一个例子。如果您使用的是Linux系统,则必须处理硬件时钟和内核托管时钟。如果更改硬件时钟,则不会受到任何影响,但是在内核管理的时钟中,您将遇到麻烦:Instant.now()获取系统时间,并显示错误的时间间隔。
Valtoni Boaventura

我什至不知道它可以在Android上运行。

不要忘记java.time.Instant是不可变的并且是线程安全的:)
Amos Kosgei

38

Spring提供了一个优雅的org.springframework.util.StopWatchClass(s​​pring-core模块)。

StopWatch stopWatch = new StopWatch();
stopWatch.start();
     // Do something
stopWatch.stop();
     System.out.println(stopWatch.getTotalTimeMillis());

8

使用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);
  }
} 

本教程的更多信息


如其他地方所述,currentTimeMillis()与系统日期/时间相关联,并且不保证其单调(例如,您可以获得负的经过时间)。
oligofren

8

代码无效,因为in中的经过变量getElapsedTimeSecs()不是a floatdouble


7

没有内置的秒表实用程序,但是从JSR-310(Java 8 Time)开始,您可以轻松地做到这一点。

ZonedDateTime now = ZonedDateTime.now();
// Do stuff
long seconds = now.until(ZonedDateTime.now(), ChronoUnit.SECONDS);

我没有对此进行基准测试,但是我猜想使用番石榴的秒表会更有效。



3

简单易用的秒表类:

import java.time.Duration;
import java.time.Instant;

public class StopWatch {

    Instant startTime, endTime;
    Duration duration;
    boolean isRunning = false;

    public void start() {
        if (isRunning) {
            throw new RuntimeException("Stopwatch is already running.");
        }
        this.isRunning = true;
        startTime = Instant.now();
    }

    public Duration stop() {
        this.endTime = Instant.now();
        if (!isRunning) {
            throw new RuntimeException("Stopwatch has not been started yet");
        }
        isRunning = false;
        Duration result = Duration.between(startTime, endTime);
        if (this.duration == null) {
            this.duration = result;
        } else {
            this.duration = duration.plus(result);
        }

        return this.getElapsedTime();
    }

    public Duration getElapsedTime() {
        return this.duration;
    }

    public void reset() {
        if (this.isRunning) {
            this.stop();
        }
        this.duration = null;
    }
}

用法:

StopWatch sw = new StopWatch();
sw.start();
    // doWork()
sw.stop();
System.out.println( sw.getElapsedTime().toMillis() + "ms");

3

使用:com.google.common.base.Stopwatch,它简单易用。

<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>23.0</version>
</dependency>

例:

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

"Do something"

logger.debug("this task took " + stopwatch.stop().elapsedTime(TimeUnit.MILLISECONDS) + " mills");

这个任务花了112磨


2

试试这个

import java.awt.event.*;

import java.awt.*;

import javax.swing.*;

public class millis extends JFrame implements ActionListener, Runnable
    {

     private long startTime;
     private final static java.text.SimpleDateFormat timerFormat = new java.text.SimpleDateFormat("mm : ss.SSS");
     private final JButton startStopButton= new JButton("Start/stop");
     private Thread updater;
     private boolean isRunning= false;
     private final Runnable displayUpdater= new Runnable()
         {
         public void run()
             {
             displayElapsedTime(System.currentTimeMillis() - millis.this.startTime);
         }
     };
     public void actionPerformed(ActionEvent ae)
         {
         if(isRunning)
             {
             long elapsed= System.currentTimeMillis() - startTime;
             isRunning= false;
             try
                 {
                 updater.join();
                 // Wait for updater to finish
             }
             catch(InterruptedException ie) {}
             displayElapsedTime(elapsed);
             // Display the end-result
         }
         else
             {
             startTime= System.currentTimeMillis();
             isRunning= true;
             updater= new Thread(this);
             updater.start();
         }
     }
     private void displayElapsedTime(long elapsedTime)
         {
         startStopButton.setText(timerFormat.format(new java.util.Date(elapsedTime)));
     }
     public void run()
         {
         try
             {
             while(isRunning)
                 {
                 SwingUtilities.invokeAndWait(displayUpdater);
                 Thread.sleep(50);
             }
         }
         catch(java.lang.reflect.InvocationTargetException ite)
             {
             ite.printStackTrace(System.err);
             // Should never happen!
         }
         catch(InterruptedException ie) {}
         // Ignore and return!
     }
     public millis()
         {
         startStopButton.addActionListener(this);
         getContentPane().add(startStopButton);
         setSize(100,50);
         setVisible(true);
     }
     public static void main(String[] arg)
         {
         new Stopwatch().addWindowListener(new WindowAdapter()
             {
             public void windowClosing(WindowEvent e)
                 {
                 System.exit(0);
             }
         });
         millis s=new millis();
         s.run();
     }
}

1
如其他地方所述,currentTimeMillis()与系统日期/时间相关联,并且不保证其单调(例如,您可以获得负的经过时间)。
oligofren

2

试试这个:

/*
 * calculates elapsed time in the form hrs:mins:secs
 */
public class StopWatch
{ 
    private Date startTime;

    public void startTiming()
    {
        startTime = new Date();
    }

    public String stopTiming()
    {
        Date stopTime = new Date();
        long timediff = (stopTime.getTime() - startTime.getTime())/1000L;
        return(DateUtils.formatElapsedTime(timediff));
    }

}

用:

StopWatch sw = new StopWatch();
...
sw.startTiming();
...
String interval = sw.stopTiming();

2
DateUtils是Apache Commons的一部分,为什么不仅仅使用它们的StopWatch?
Bill Effin Murray

在大多数情况下,您将使用其他答案中提到的一些公共库(例如Apache Commons)。如果您不需要所有内容,甚至可以只使用其中的一部分。
Guyarad '16

2

试试这个。

public class StopWatch { 

      private long startTime = 0;
      private long stopTime = 0;

      public StopWatch()
      {
            startTime = System.currentTimeMillis();
      }

      public void start() {
        startTime = System.currentTimeMillis();
      }

      public void stop() {
        stopTime = System.currentTimeMillis();
        System.out.println("StopWatch: " + getElapsedTime() + " milliseconds.");
        System.out.println("StopWatch: " + getElapsedTimeSecs() + " seconds.");
      }

      /**
       * @param process_name
       */
      public void stop(String process_name) {
            stopTime = System.currentTimeMillis();
            System.out.println(process_name + " StopWatch: " + getElapsedTime() + " milliseconds.");
            System.out.println(process_name + " StopWatch: " + getElapsedTimeSecs() + " seconds.");
      }      

      //elaspsed time in milliseconds
      public long getElapsedTime() {
          return stopTime - startTime;
      }

      //elaspsed time in seconds
      public double getElapsedTimeSecs() {
        double elapsed;
          elapsed = ((double)(stopTime - startTime)) / 1000;
        return elapsed;
      }
} 

用法:

StopWatch watch = new StopWatch();
// do something
watch.stop();

安慰:

StopWatch: 143 milliseconds.
StopWatch: 0.143 seconds.

尽管这可能是问题的要求,也可能不是,但您的回答帮助我解决了我的问题。谢谢。
Toiletduck

currentTimeMillis()与系统日期/时间相关,并且不保证其单调(例如,您可以得到负的经过时间)。
oligofren

如果您决定自己建造,则只需使用System.nanoTime()即可始终获得正确的结果。
oligofren

2

Performetrics提供了便捷的秒表类,正是您所需要的方式。它可以测量时钟时间以及更多时间:如果需要,它还可以测量CPU时间(用户时间和系统时间)。它小巧,免费,您可以从Maven Central下载。更多信息和示例可以在这里找到:https : //obvj.net/performetrics

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

// Your code

sw.stop();
sw.printStatistics(System.out);

// Sample output:
// +-----------------+----------------------+--------------+
// | Counter         |         Elapsed time | Time unit    |
// +-----------------+----------------------+--------------+
// | Wall clock time |             85605718 | nanoseconds  |
// | CPU time        |             78000500 | nanoseconds  |
// | User time       |             62400400 | nanoseconds  |
// | System time     |             15600100 | nanoseconds  |
// +-----------------+----------------------+--------------+

您可以将指标转换为任何时间单位(纳秒,毫秒,秒等)。

PS:我是该工具的作者。



1

试试这个。

Java秒表完全可用的解决方案

在这里,您将获得完整的解决方案。

上面链接的解决方案中的一小段:

您可以像下面的代码一样创建一个类,并在代码部分之前和之后使用此类的start和stop方法,以测量所需的时间。

public class Stopwatch{
  private long startTime;
  private long stopTime;

  /**
   starting the stop watch.
  */
  public void start(){
        startTime = System.nanoTime();
  }

  /**
   stopping the stop watch.
  */
  public void stop()
  {     stopTime = System.nanoTime(); }

  /**
  elapsed time in nanoseconds.
  */
  public long time(){
        return (stopTime - startTime);
  }

  public String toString(){
      return "elapsed time: " + time() + " nanoseconds.";
  }

}

谢谢。


1
尽管此链接可以回答问题,但最好在此处包括答案的基本部分,并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会无效。
AS Mackay

感谢@ASMackay的建议。我完全同意你的观点。
Sukriti Sarkar,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.