DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Singleton: 6 Ways To Write and Use in Java Programming
  • Google Guava and Its Two Fantastic Libraries: Graph and Eventbus

Trending

  • Unlocking Data with Language: Real-World Applications of Text-to-SQL Interfaces
  • Concourse CI/CD Pipeline: Webhook Triggers
  • Blue Skies Ahead: An AI Case Study on LLM Use for a Graph Theory Related Application
  • Cookies Revisited: A Networking Solution for Third-Party Cookies
  1. DZone
  2. Coding
  3. Java
  4. Guava Stopwatch

Guava Stopwatch

By 
Dustin Marx user avatar
Dustin Marx
·
Dec. 28, 11 · Interview
Likes (12)
Comment
Save
Tweet
Share
28.0K Views

Join the DZone community and get the full member experience.

Join For Free

Guava's Stopwatch is another Guava class new to Guava Release 10 (as is Optional, the subject of another recent post). As its name implies, this simple class provides a method to conveniently measure time elapsed between two code points. It has several advantages over use of System.currentTimeMillis() or System.nanoTime(). I don't focus on these advantages here, but the Javadoc documentation for Stopwatch does cover some of these advantages.

As is true of many of Guava's classes, one of the endearing features of Stopwatch is its simplicity and appropriately named methods. The class features two constructors, one that takes no arguments (likely to be most commonly used) and one that accepts an customized extension of the Ticker class. Once an instance of Stopwatch is obtained, it's a simple matter of using methods with "obvious" names like start(), stop(), and reset() to control the stopwatch.

Any given Stopwatch instance records elapsed time in a cumulative fashion. In other words, you can start and stop the stopwatch multiple times (just don't start an already started stopwatch and don't stop an already stopped stopwatch) and the elapsed time accumulates with each start and stop. If that's not what is wanted and a single instance of the stopwatch is to be used to measure independent events (but not concurrent events), then the reset() method is used between the last run's stop() and the next run's start().

I have already alluded to several caveats to keep in mind when using Guava's Stopwatch. First, two successive start() methods should not be invoked on a given instance of Stopwatch without first stopping it with stop() before making the second call to stop(). Stopwatch has an instance method isRunning() that is useful for detecting a running stopwatch before trying to start it again or even before trying to stop one that has already been stopped or was never started. Most of these issues such as starting the stopwatch twice without stopping it or stopping a stopwatch that is not running or was never started lead to IllegalStateExceptions being thrown. Guava developers make use of their own Preconditions class to ascertain these aberrant conditions and to the throwing of these exceptions. The further implication of this, which is spelled out in the Javadoc documentation, is that Stopwatch is not thread-safe and should be used in a single-thread environment.

The methods covered so far handle constructing instances of Stopwatch and managing the stopwatch. However, a stopwatch is almost always useful only when the timed results are available for viewing. The Stopwatch class provides two main methods for accessing elapsed time recorded by the stopwatch instance. One method, elapsedMillis(), is similar to standard Java methods that return milliseconds since epoch time. The big difference here is that Stopwatch is returning milliseconds elapsed between given points in time (start() and stop() calls) versus since an absolute epoch time.

I prefer elapsedTime(TimeUnit) for acquiring the elapsed time recorded in my stopwatch instance. This method makes use of the TimeUnit enum (see my post on TimeUnit) to specify the units that the elapsed time should be expressed in. Both of these methods for reporting elapsed time can be run while the stopwatch is running or after it has stopped.

The following code listing contains a class that demonstrates the methods on Stopwatch that have been highlighted in this post.

StopWatchDemo.java
package dustin.examples;

import static java.lang.System.out;

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

/**
 * Demonstrates Guava's (Release 10) Stopwatch class.
 * 
 * @author Dustin
 */
public class StopWatchDemo
{
   private final static Logger LOGGER = Logger.getLogger(StopWatchDemo.class.getCanonicalName());

   public static void doSomethingJustToBeDoingIt(final int numberOfTimesToDoNothing)
   {
      for (int count=0; count < numberOfTimesToDoNothing; count++)
      {
         try
         {
            Thread.sleep(TimeUnit.SECONDS.toMillis(1));
         }
         catch (InterruptedException interruptEx)
         {
            LOGGER.log(Level.INFO, "Don't interrupt me when I'm trying to sleep!", interruptEx);
         }
      }
   }

   /**
    * Print statistics on Stopwatch-reported times for provided number of loops.
    * 
    * @param numberLoops Number of loops executed.
    * @param stopwatch Stopwatch instance with time used statistics.
    */
   public static void printElapsedTime(final int numberLoops, final Stopwatch stopwatch)
   {
      if (stopwatch.isRunning())
      {
         out.println("WARNING! Your stopwatch is still running!");
      }
      else // stopwatch not running
      {
         out.println(numberLoops + " loops required: ");
         out.println("\t" + stopwatch.toString(6));
         out.println("\t" + stopwatch.elapsedMillis() + " elapsed milliseconds.");
         out.println("\t" + stopwatch.elapsedTime(TimeUnit.MINUTES) + " minutes");
         out.println("\t" + stopwatch.elapsedTime(TimeUnit.SECONDS) + " seconds");
         out.println("\t" + stopwatch.elapsedTime(TimeUnit.MILLISECONDS) + " milliseconds");
         out.println("\t" + stopwatch.elapsedTime(TimeUnit.NANOSECONDS) + " nanoseconds");
      }
   }

   public static void main(final String[] arguments)
   {
      final Stopwatch stopwatch = new Stopwatch();

      int numberTimes = 5;
      stopwatch.start();
      doSomethingJustToBeDoingIt(numberTimes);
      stopwatch.stop();
      printElapsedTime(numberTimes, stopwatch);

      numberTimes = 45;
      stopwatch.reset();
      stopwatch.start();
      doSomethingJustToBeDoingIt(numberTimes);
      stopwatch.stop();
      printElapsedTime(numberTimes, stopwatch);

      numberTimes = 125;
      stopwatch.reset();
      stopwatch.start();
      doSomethingJustToBeDoingIt(numberTimes);
      stopwatch.stop();
      printElapsedTime(numberTimes, stopwatch);
   }
}

When the above code is executed, its output is similar to that shown in the following screen snapshot.

If I comment out the lines that reset the stop watch instance, the stopwatch instance accumulates elapsed time rather than tracking it separately. This difference is shown in the next screen snapshot.

The Guava Stopwatch class makes it easy to perform simple timing measurements to analyze how long certain operations take. It is easy to use and provides the flexibility to readily provide output in the desired time scale.

 

From http://marxsoftware.blogspot.com/2011/10/guava-stopwatch.html

Google Guava

Opinions expressed by DZone contributors are their own.

Related

  • Singleton: 6 Ways To Write and Use in Java Programming
  • Google Guava and Its Two Fantastic Libraries: Graph and Eventbus

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!