2010-12-11 03:35:12 +08:00
|
|
|
package org.broadinstitute.sting.utils;
|
|
|
|
|
|
|
|
|
|
|
2012-09-02 23:37:30 +08:00
|
|
|
import com.google.java.contract.Ensures;
|
|
|
|
|
import com.google.java.contract.Requires;
|
|
|
|
|
|
|
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
2010-12-11 03:35:12 +08:00
|
|
|
/**
|
2012-09-02 23:37:30 +08:00
|
|
|
* A useful simple system for timing code with nano second resolution
|
|
|
|
|
*
|
|
|
|
|
* Note that this code is not thread-safe. If you have a single timer
|
|
|
|
|
* being started and stopped by multiple threads you will need to protect the
|
|
|
|
|
* calls to avoid meaningless results of having multiple starts and stops
|
|
|
|
|
* called sequentially.
|
2010-12-11 03:35:12 +08:00
|
|
|
*
|
|
|
|
|
* User: depristo
|
|
|
|
|
* Date: Dec 10, 2010
|
|
|
|
|
* Time: 9:07:44 AM
|
|
|
|
|
*/
|
|
|
|
|
public class SimpleTimer {
|
2012-09-02 23:37:30 +08:00
|
|
|
protected static final double NANO_TO_SECOND_DOUBLE = 1.0 / TimeUnit.SECONDS.toNanos(1);
|
|
|
|
|
private final String name;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The elapsedTimeNano time in nanoSeconds of this timer. The elapsedTimeNano time is the
|
|
|
|
|
* sum of times between starts/restrats and stops.
|
|
|
|
|
*/
|
|
|
|
|
private long elapsedTimeNano = 0l;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The start time of the last start/restart in nanoSeconds
|
|
|
|
|
*/
|
|
|
|
|
private long startTimeNano = 0l;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Is this timer currently running (i.e., the last call was start/restart)
|
|
|
|
|
*/
|
|
|
|
|
private boolean running = false;
|
2010-12-11 03:35:12 +08:00
|
|
|
|
2011-05-23 03:45:31 +08:00
|
|
|
/**
|
|
|
|
|
* Creates an anonymous simple timer
|
|
|
|
|
*/
|
|
|
|
|
public SimpleTimer() {
|
|
|
|
|
this("Anonymous");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Creates a simple timer named name
|
|
|
|
|
* @param name of the timer, must not be null
|
|
|
|
|
*/
|
2012-09-02 23:37:30 +08:00
|
|
|
public SimpleTimer(final String name) {
|
|
|
|
|
if ( name == null ) throw new IllegalArgumentException("SimpleTimer name cannot be null");
|
2010-12-11 03:35:12 +08:00
|
|
|
this.name = name;
|
|
|
|
|
}
|
|
|
|
|
|
2011-05-23 03:45:31 +08:00
|
|
|
/**
|
|
|
|
|
* @return the name associated with this timer
|
|
|
|
|
*/
|
2011-10-18 01:37:55 +08:00
|
|
|
public synchronized String getName() {
|
2010-12-11 03:35:12 +08:00
|
|
|
return name;
|
|
|
|
|
}
|
|
|
|
|
|
2011-05-23 03:45:31 +08:00
|
|
|
/**
|
2012-09-02 23:37:30 +08:00
|
|
|
* Starts the timer running, and sets the elapsedTimeNano time to 0. This is equivalent to
|
2011-05-23 03:45:31 +08:00
|
|
|
* resetting the time to have no history at all.
|
|
|
|
|
*
|
|
|
|
|
* @return this object, for programming convenience
|
|
|
|
|
*/
|
2012-09-02 23:37:30 +08:00
|
|
|
@Ensures("elapsedTimeNano == 0l")
|
2011-10-14 03:53:12 +08:00
|
|
|
public synchronized SimpleTimer start() {
|
2012-09-02 23:37:30 +08:00
|
|
|
elapsedTimeNano = 0l;
|
|
|
|
|
return restart();
|
2010-12-11 03:35:12 +08:00
|
|
|
}
|
|
|
|
|
|
2011-05-23 03:45:31 +08:00
|
|
|
/**
|
2012-09-02 23:37:30 +08:00
|
|
|
* Starts the timer running, without resetting the elapsedTimeNano time. This function may be
|
2011-05-23 03:45:31 +08:00
|
|
|
* called without first calling start(). The only difference between start and restart
|
2012-09-02 23:37:30 +08:00
|
|
|
* is that start resets the elapsedTimeNano time, while restart does not.
|
2011-05-23 03:45:31 +08:00
|
|
|
*
|
|
|
|
|
* @return this object, for programming convenience
|
|
|
|
|
*/
|
2011-10-14 03:53:12 +08:00
|
|
|
public synchronized SimpleTimer restart() {
|
2010-12-11 03:35:12 +08:00
|
|
|
running = true;
|
2012-09-02 23:37:30 +08:00
|
|
|
startTimeNano = currentTimeNano();
|
2010-12-11 03:35:12 +08:00
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
2011-05-23 03:45:31 +08:00
|
|
|
/**
|
|
|
|
|
* @return is this timer running?
|
|
|
|
|
*/
|
2011-10-18 01:37:55 +08:00
|
|
|
public synchronized boolean isRunning() {
|
2011-05-23 03:45:31 +08:00
|
|
|
return running;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return A convenience function to obtain the current time in milliseconds from this timer
|
|
|
|
|
*/
|
2012-09-02 23:37:30 +08:00
|
|
|
public long currentTime() {
|
2010-12-11 03:35:12 +08:00
|
|
|
return System.currentTimeMillis();
|
|
|
|
|
}
|
|
|
|
|
|
2011-05-23 03:45:31 +08:00
|
|
|
/**
|
2012-09-02 23:37:30 +08:00
|
|
|
* @return A convenience function to obtain the current time in nanoSeconds from this timer
|
|
|
|
|
*/
|
|
|
|
|
public long currentTimeNano() {
|
|
|
|
|
return System.nanoTime();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Stops the timer. Increases the elapsedTimeNano time by difference between start and now.
|
|
|
|
|
*
|
|
|
|
|
* It's ok to call stop on a timer that's not running. It has no effect on the timer.
|
2011-05-23 03:45:31 +08:00
|
|
|
*
|
|
|
|
|
* @return this object, for programming convenience
|
|
|
|
|
*/
|
2012-09-02 23:37:30 +08:00
|
|
|
@Requires("startTimeNano != 0l")
|
2011-10-14 03:53:12 +08:00
|
|
|
public synchronized SimpleTimer stop() {
|
2012-09-02 23:37:30 +08:00
|
|
|
if ( running ) {
|
|
|
|
|
running = false;
|
|
|
|
|
elapsedTimeNano += currentTimeNano() - startTimeNano;
|
|
|
|
|
}
|
2010-12-11 03:35:12 +08:00
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
2011-05-23 03:45:31 +08:00
|
|
|
/**
|
2012-09-02 23:37:30 +08:00
|
|
|
* Returns the total elapsedTimeNano time of all start/stops of this timer. If the timer is currently
|
2011-05-23 03:45:31 +08:00
|
|
|
* running, includes the difference from currentTime() and the start as well
|
|
|
|
|
*
|
|
|
|
|
* @return this time, in seconds
|
|
|
|
|
*/
|
2011-10-14 03:53:12 +08:00
|
|
|
public synchronized double getElapsedTime() {
|
2012-09-02 23:37:30 +08:00
|
|
|
return nanoToSecondsAsDouble(getElapsedTimeNano());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected static double nanoToSecondsAsDouble(final long nano) {
|
|
|
|
|
return nano * NANO_TO_SECOND_DOUBLE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @see #getElapsedTime() but returns the result in nanoseconds
|
|
|
|
|
*
|
|
|
|
|
* @return the elapsed time in nanoseconds
|
|
|
|
|
*/
|
|
|
|
|
public synchronized long getElapsedTimeNano() {
|
|
|
|
|
return running ? (currentTimeNano() - startTimeNano + elapsedTimeNano) : elapsedTimeNano;
|
2010-12-11 03:35:12 +08:00
|
|
|
}
|
|
|
|
|
}
|