Is there a stopwatch in Java?
Asked Answered
M

18

146

Is there a stopwatch in Java?
On Google I only found code of stopwatches that don't work - they always return 0 milliseconds.

This code I found doesn't work and I don't see why.

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;
  }
}
Matti answered 24/11, 2011 at 10:42 Comment(4)
And how do you determin it didn't work ? (perhaps you're measuring something that takes less time to execute than the accuracy of System.currentTimeMillis())Punk
Please post the code how you are testing this class...Maker
Just wanted to note that this is one of the textbook questions in "Introduction to Java Programming, Comprehensive Version (9th Edition)".Vostok
Please don't use currentTimeMillis() for production, as it's tied to system date/time and is not guaranteed to be monotonous (e.g. you can get negative elapsed time). For measuring time use nanoTime() – it's guaranteed to be monotonous and intended exactly for measuring purpose. See docs.oracle.com/javase/8/docs/api/java/lang/…Wardwarde
L
109

You'll find one in

http://commons.apache.org/lang/

It's called

org.apache.commons.lang.time.StopWatch

But it roughly does the same as yours. If you're in for more precision, use

System.nanoTime()

See also this question here:

Time measuring overhead in Java

Leila answered 24/11, 2011 at 10:44 Comment(0)
W
102

Use Guava's Stopwatch class.

An object that measures elapsed time in nanoseconds. It is useful to measure elapsed time using this class instead of direct calls to System.nanoTime() for a few reasons:

  • An alternate time source can be substituted, for testing or performance reasons.
  • As documented by nanoTime, the value returned has no absolute meaning, and can only be interpreted as relative to another timestamp returned by nanoTime at a different time. Stopwatch is a more effective abstraction because it exposes only these relative values, not the absolute ones.

Basic usage:

Stopwatch stopwatch = Stopwatch.createStarted();
doSomething();
stopwatch.stop(); // optional

Duration duration = stopwatch.elapsed();

log.info("time: " + stopwatch); // formatted string like "12.3 ms"
Waylay answered 24/11, 2011 at 10:44 Comment(4)
guavas stopwatch is missing getStartTime(), apache is missing isRunning() ahhhhApoplectic
@ToKra What would you do with the start time anyway? Since it's nano time, you can't use it for anything meaningful anyway, as described in the docs.Lubber
Now you use this to get the milliseconds: long stopWatch = stopWatch.elapsed(TimeUnit.MILLISECONDS);Thirteenth
Which guava version is it? I used 1.8 and it didn't find the Stopwatch classVickivickie
S
89

Now you can try something like:

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

Output is in ISO 8601.

Spoilage answered 3/11, 2015 at 9:43 Comment(7)
Quick and easy, thank you very much! Helps keep track of task duration from start.Ulphia
What if you change the system time during the sleep?Gallenz
@Gallenz its only an example. If you're on a linux box you must deal with hardware clock and kernel managed clock. If you change hardware clock, none will be affected but in kernel managed clock you will be in trouble: Instant.now() get the system time and will show a wrong time interval.Spoilage
I did not even know it worked on Android. Good to know :)Spoilage
Not forgetting java.time.Instant is immutable and thread safe :)Hogfish
Lack of import statements aside, this throws an InterruptedException.Consolatory
With java 8 imports, It’s only a sample, David. Please adapt before going to production.Spoilage
D
58

Spring provides an elegant org.springframework.util.StopWatch class (spring-core module).

StopWatch stopWatch = new StopWatch();

stopWatch.start();
// Do something
stopWatch.stop();

System.out.println(stopWatch.getTotalTimeMillis());
Douglass answered 6/12, 2012 at 9:41 Comment(0)
A
9

There's no built in Stopwatch utility but as of JSR-310 (Java 8 Time) you can do this simply.

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

I haven't benchmarked this properly but I would guess using Guava's Stopwatch is more effective.

Antinucleon answered 9/7, 2015 at 9:50 Comment(0)
A
8

The code doesn't work because elapsed variable in getElapsedTimeSecs() is not a float or double.

Alto answered 23/8, 2012 at 13:47 Comment(0)
G
7

Use System.currentTimeMillis() to get the start time and the end time and calculate the difference.

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

More info at this tutorial

Gelt answered 24/5, 2013 at 13:9 Comment(2)
As said elsewhere, currentTimeMillis() is tied to system date/time and is not guaranteed to be monotonous (e.g. you can get negative elapsed time).Martainn
Do not use System.currentTimeMillis() to measure elapsed time.Acroterion
V
3

Try this:

/*
 * 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));
    }

}

Use:

StopWatch sw = new StopWatch();
...
sw.startTiming();
...
String interval = sw.stopTiming();
Viewfinder answered 24/1, 2014 at 0:35 Comment(2)
DateUtils is part of Apache Commons, why not just use their StopWatch?Frontispiece
In most cases you'll use some common library like mentioned in other answers (Apache Commons for instance). You can even take only parts of the library with if you don't need everything.Merca
R
3

use : com.google.common.base.Stopwatch, its simple and easy.

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

example:

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

"Do something"

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

this task took 112 mills

Rhynd answered 26/9, 2017 at 9:13 Comment(0)
C
2

try this

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();
     }
}
Construction answered 7/11, 2012 at 16:19 Comment(1)
As said elsewhere, currentTimeMillis() is tied to system date/time and is not guaranteed to be monotonous (e.g. you can get negative elapsed time).Martainn
C
2

try this http://introcs.cs.princeton.edu/java/stdlib/Stopwatch.java.html

that's very easy

Stopwatch st = new Stopwatch();
// Do smth. here
double time = st.elapsedTime(); // the result in millis

This class is a part of stdlib.jar

Congruent answered 21/9, 2013 at 17:34 Comment(0)
S
2

Simple out of the box Stopwatch class:

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

Usage:

StopWatch sw = new StopWatch();
sw.start();
    // doWork()
sw.stop();
System.out.println( sw.getElapsedTime().toMillis() + "ms");
Streak answered 21/4, 2016 at 3:15 Comment(0)
P
2

Try this.

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

Usage:

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

Console:

StopWatch: 143 milliseconds.
StopWatch: 0.143 seconds.
Pretor answered 6/7, 2017 at 5:38 Comment(3)
Although this may or may not be what was being asked for in the question, your answer helped me with my problem. Thank you.Swede
currentTimeMillis() is tied to system date/time and is not guaranteed to be monotonous (e.g. you can get negative elapsed time).Martainn
If you decide to build your own, just use System.nanoTime() to always get correct results.Martainn
P
2

Performetrics provides a convenient Stopwatch class, just the way you need. It can measure wall-clock time and more: it also measures CPU time (user time and system time) if you need. It's small, free and you can download from Maven Central. More information and examples can be found here: 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  |
// +-----------------+----------------------+--------------+

You can convert the metrics to any time unit (nanoseconds, milliseconds, seconds, etc...)

PS: I am the author of the tool.

Possessive answered 21/1, 2020 at 17:13 Comment(0)
B
1

You can find a convenient one here:

https://github.com/varra4u/utils4j/blob/master/src/main/java/com/varra/util/StopWatch.java

Usage:

final StopWatch timer = new StopWatch();
System.out.println("Timer: " + timer);
System.out.println("ElapsedTime: " + timer.getElapsedTime());
Burglarize answered 27/3, 2016 at 9:12 Comment(0)
L
1

Try this.

Java Stopwatch Fully Working Solution

Here you will get a fully working solution.

Just a snippet from the above-linked solution:

You can create a class like below code and use this class' start and stop method before and after the code section, you want to measure the time taken.

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.";
  }

}

Thank you.

Likelihood answered 18/7, 2019 at 6:31 Comment(2)
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes.Carbamidine
Thanks @ASMackay for your suggestion. I completely agree with you.Likelihood
P
0

Try this...

import java.util.concurrent.TimeUnit;
import com.google.common.base.Stopwatch;

public class StopwatchTest {
     
    public static void main(String[] args) throws Exception {
        Stopwatch stopwatch = Stopwatch.createStarted();
        Thread.sleep(1000 * 60);
        stopwatch.stop(); // optional
        long millis = stopwatch.elapsed(TimeUnit.MILLISECONDS);
        System.out.println("Time in milliseconds "+millis);
        System.out.println("that took: " + stopwatch);
    }
}
Popup answered 28/9, 2020 at 6:51 Comment(0)
P
0

I have created a Stopwatch that has everything you might need in it.

I even documented it!

And I also compiled it for faster usage.

Here's an example:

//...
  //For demo only!
  public static void main(String[]a){
    final Stopwatch stopwatch=new Stopwatch();
    stopwatch.start();
    try{
      java.lang.Thread.sleep(1000);
    }catch(Exception e){}
    stopwatch.split();
    System.out.println("Time elapsed in nanoseconds: "+stopwatch.getTimeElapsed());
    System.out.println("Time elapsed in milliseconds: "+stopwatch.getTimeElapsed(Stopwatch.millis));
    System.out.println("Time elapsed in seconds: "+stopwatch.getTimeElapsed(Stopwatch.seconds));
    try{
      java.lang.Thread.sleep(1000);
    }catch(Exception e){}
    stopwatch.split();
    final long[][] laps=stopwatch.getLaps();
    for(long[] lap:laps){
      System.out.println(java.util.Arrays.toString(lap));
    }
  }
//...

This is not for promotion, made this to help people not waste their time in coding classes themselves!

Premiership answered 17/7, 2022 at 4:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.