/* * Copyright 1999-2002 Carnegie Mellon University. * Portions Copyright 2002 Sun Microsystems, Inc. * Portions Copyright 2002 Mitsubishi Electric Research Laboratories. * All Rights Reserved. Use is subject to license terms. * * See the file "license.terms" for information on usage and * redistribution of this file, and for a DISCLAIMER OF ALL * WARRANTIES. * */ package edu.cmu.sphinx.util; import java.text.DecimalFormat; import java.util.logging.Logger; /** * Keeps track of execution times. This class provides methods that can be used for timing processes. The process to be * timed should be bracketed by calls to timer.start() and timer.stop(). Repeated operations can be timed more than * once. The timer will report the minimum, maximum, average and last time executed for all start/stop pairs when the * timer.dump is called. * <p> * Timer instances can be obtained from a global cache implemented in {@code TimerPool}. * * @see TimerPool */ public class Timer { private final static DecimalFormat timeFormatter = new DecimalFormat("###0.0000"); private final String name; private double sum; private long count; private long startTime; private long curTime; private long minTime = Long.MAX_VALUE; private long maxTime; private boolean notReliable; // if true, timing is not reliable /** * Creates a timer. * * @param name the name of the timer */ Timer(String name) { assert name != null : "timers must have a name!"; this.name = name; reset(); } /** * Retrieves the name of the timer * * @return the name of the timer */ public String getName() { return name; } /** Resets the timer as if it has never run before. */ public void reset() { startTime = 0L; count = 0L; sum = 0L; minTime = Long.MAX_VALUE; maxTime = 0L; notReliable = false; } /** * Returns true if the timer has started. * * @return true if the timer has started; false otherwise */ public boolean isStarted() { return (startTime > 0L); } /** Starts the timer running. */ public void start() { if (startTime != 0L) { notReliable = true; // start called while timer already running System.out.println (getName() + " timer.start() called without a stop()"); } startTime = System.currentTimeMillis(); } /** * Starts the timer at the given time. * * @param time the starting time */ public void start(long time) { if (startTime != 0L) { notReliable = true; // start called while timer already running System.out.println (getName() + " timer.start() called without a stop()"); } if (time > System.currentTimeMillis()) { throw new IllegalStateException ("Start time is later than current time"); } startTime = time; } /** * Stops the timer. * * @return the duration since start in milliseconds */ public long stop() { if (startTime == 0L) { notReliable = true; // stop called, but start never called System.out.println (getName() + " timer.stop() called without a start()"); } curTime = System.currentTimeMillis() - startTime; startTime = 0L; if (curTime > maxTime) { maxTime = curTime; } if (curTime < minTime) { minTime = curTime; } count++; sum += curTime; return curTime; } /** * Dump the timer. Shows the timer details. * @param logger to use for dump */ public void dump(Logger logger) { showTimesShort(logger); } /** * Gets the count of starts for this timer * * @return the count */ public long getCount() { return count; } /** * Returns the latest time gathered * * @return the time in milliseconds */ public long getCurTime() { return curTime; } /** * Gets the average time for this timer in milliseconds * * @return the average time */ public double getAverageTime() { if (count == 0) { return 0.0; } return sum / count; } /** * Gets the min time for this timer in milliseconds * * @return the min time */ public long getMinTime() { return minTime; } /** * Gets the max time for this timer in milliseconds * * @return the max time in milliseconds */ public long getMaxTime() { return maxTime; } /** * Formats times into a standard format. * * @param time the time (in milliseconds) to be formatted * @return a string representation of the time. */ private String fmtTime(long time) { return fmtTime(time / 1000.0); } /** * Formats times into a standard format. * * @param time the time (in seconds) to be formatted * @return a string representation of the time. */ private String fmtTime(double time) { return Utilities.pad(timeFormatter.format(time) + 's', 10); } /** Shows brief timing statistics . * @param logger */ private void showTimesShort(Logger logger) { double avgTime = 0.0; if (count == 0) { return; } if (count > 0) { avgTime = sum / count / 1000.0; } if (notReliable) { logger.info(Utilities.pad(name, 20) + ' ' + "Not reliable."); } else { logger.info(Utilities.pad(name, 20) + ' ' + Utilities.pad(String.valueOf(count), 8) + fmtTime(curTime) + fmtTime(minTime) + fmtTime(maxTime) + fmtTime(avgTime) + fmtTime(sum / 1000.0)); } } }