src/core/net/sf/basedb/util/timer/PerformanceTimer.java

Code
Comments
Other
Rev Date Author Line
3663 14 Aug 07 nicklas 1 /**
3663 14 Aug 07 nicklas 2   $Id$
3663 14 Aug 07 nicklas 3
3675 16 Aug 07 jari 4   Copyright (C) 2007 Nicklas Nordborg
3663 14 Aug 07 nicklas 5
3663 14 Aug 07 nicklas 6   This file is part of BASE - BioArray Software Environment.
3663 14 Aug 07 nicklas 7   Available at http://base.thep.lu.se/
3663 14 Aug 07 nicklas 8
3663 14 Aug 07 nicklas 9   BASE is free software; you can redistribute it and/or
3663 14 Aug 07 nicklas 10   modify it under the terms of the GNU General Public License
4479 05 Sep 08 jari 11   as published by the Free Software Foundation; either version 3
3663 14 Aug 07 nicklas 12   of the License, or (at your option) any later version.
3663 14 Aug 07 nicklas 13
3663 14 Aug 07 nicklas 14   BASE is distributed in the hope that it will be useful,
3663 14 Aug 07 nicklas 15   but WITHOUT ANY WARRANTY; without even the implied warranty of
3663 14 Aug 07 nicklas 16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
3663 14 Aug 07 nicklas 17   GNU General Public License for more details.
3663 14 Aug 07 nicklas 18
3663 14 Aug 07 nicklas 19   You should have received a copy of the GNU General Public License
4515 11 Sep 08 jari 20   along with BASE. If not, see <http://www.gnu.org/licenses/>.
3663 14 Aug 07 nicklas 21 */
3663 14 Aug 07 nicklas 22 package net.sf.basedb.util.timer;
3663 14 Aug 07 nicklas 23
3663 14 Aug 07 nicklas 24 /**
3663 14 Aug 07 nicklas 25   A simple timer for measuring code performance. You can register
3663 14 Aug 07 nicklas 26   one or more timers when constructing an object of this class. Typically,
3663 14 Aug 07 nicklas 27   there should be one timer for each part of the code (method call) that
3663 14 Aug 07 nicklas 28   you want to measure.
3663 14 Aug 07 nicklas 29   Use {@link #start(int)}, {@link #stop(int)} and {@link #stopStart(int, int)}
3663 14 Aug 07 nicklas 30   to start and stop the timers in your code. Example:
3663 14 Aug 07 nicklas 31   
3663 14 Aug 07 nicklas 32 <pre class="code">
3663 14 Aug 07 nicklas 33 PerformanceTimer timer =
3663 14 Aug 07 nicklas 34   new PerformanceTimer("method1()", "method2()");
3663 14 Aug 07 nicklas 35 timer.start(0);
3663 14 Aug 07 nicklas 36 method1();
3663 14 Aug 07 nicklas 37 timer.stopStart(0, 1);
3663 14 Aug 07 nicklas 38 method2();
3663 14 Aug 07 nicklas 39 timer.stop(1);
3663 14 Aug 07 nicklas 40 System.out.println(timer.toString());
3663 14 Aug 07 nicklas 41 </pre>
3663 14 Aug 07 nicklas 42
3663 14 Aug 07 nicklas 43   This classes use {@link System#nanoTime()} to get the time. All times
3663 14 Aug 07 nicklas 44   are returned as nano-second differences between the start and stop time
3663 14 Aug 07 nicklas 45   of the timer. Starting and stopping a timer multiple times adds more
3663 14 Aug 07 nicklas 46   time to the timer. Use {@link #reset(int)} to zero a timer.
3663 14 Aug 07 nicklas 47
3663 14 Aug 07 nicklas 48   @author nicklas
3663 14 Aug 07 nicklas 49   @version 2.4
3663 14 Aug 07 nicklas 50   @base.modified $Date$
3663 14 Aug 07 nicklas 51 */
3663 14 Aug 07 nicklas 52 public class PerformanceTimer
3663 14 Aug 07 nicklas 53 {
3663 14 Aug 07 nicklas 54
3663 14 Aug 07 nicklas 55   private final String[] names;
3663 14 Aug 07 nicklas 56   private final long[] timers;
3663 14 Aug 07 nicklas 57   private final boolean[] isRunning;
3663 14 Aug 07 nicklas 58   /**
3663 14 Aug 07 nicklas 59     Create a new timer object for measuring one or more times.
3663 14 Aug 07 nicklas 60     
3663 14 Aug 07 nicklas 61     @param names The name of the timers
3663 14 Aug 07 nicklas 62   */
3663 14 Aug 07 nicklas 63   public PerformanceTimer(String... names)
3663 14 Aug 07 nicklas 64   {
3663 14 Aug 07 nicklas 65     this.names = names;
3663 14 Aug 07 nicklas 66     this.timers = new long[names.length];
3663 14 Aug 07 nicklas 67     this.isRunning = new boolean[names.length];
3663 14 Aug 07 nicklas 68   }
3663 14 Aug 07 nicklas 69   
3663 14 Aug 07 nicklas 70   /**
3663 14 Aug 07 nicklas 71     Start the timer with the given index. This method does nothing
3663 14 Aug 07 nicklas 72     if the timer is already running.
3663 14 Aug 07 nicklas 73     
3663 14 Aug 07 nicklas 74     @param index The index of the timer
3663 14 Aug 07 nicklas 75   */
3663 14 Aug 07 nicklas 76   public void start(int index)
3663 14 Aug 07 nicklas 77   {
3663 14 Aug 07 nicklas 78     if (isRunning[index]) return;
3663 14 Aug 07 nicklas 79     timers[index] -= System.nanoTime();
3663 14 Aug 07 nicklas 80     isRunning[index] = true;
3663 14 Aug 07 nicklas 81   }
3663 14 Aug 07 nicklas 82   
3663 14 Aug 07 nicklas 83   /**
3663 14 Aug 07 nicklas 84     Stop a running timer. This method does nothing if the timer
3663 14 Aug 07 nicklas 85     isn't running.
3663 14 Aug 07 nicklas 86     
3663 14 Aug 07 nicklas 87     @param index The index of the timer
3663 14 Aug 07 nicklas 88     @return The current time
3663 14 Aug 07 nicklas 89   */
3663 14 Aug 07 nicklas 90   public long stop(int index)
3663 14 Aug 07 nicklas 91   {
3663 14 Aug 07 nicklas 92     if (isRunning[index]) timers[index] += System.nanoTime();
3663 14 Aug 07 nicklas 93     isRunning[index] = false;
3663 14 Aug 07 nicklas 94     return timers[index];
3663 14 Aug 07 nicklas 95   }
3663 14 Aug 07 nicklas 96   
3663 14 Aug 07 nicklas 97   /**
3663 14 Aug 07 nicklas 98     Start one timer and stop another.
3663 14 Aug 07 nicklas 99     @param stopIndex The timer to stop
3663 14 Aug 07 nicklas 100     @param startIndex The timer to start
3663 14 Aug 07 nicklas 101     @return The current time of the stopped timer
3663 14 Aug 07 nicklas 102   */
3663 14 Aug 07 nicklas 103   public long stopStart(int stopIndex, int startIndex)
3663 14 Aug 07 nicklas 104   {
3663 14 Aug 07 nicklas 105     start(startIndex);
3663 14 Aug 07 nicklas 106     return stop(stopIndex);
3663 14 Aug 07 nicklas 107   }
3663 14 Aug 07 nicklas 108   
3663 14 Aug 07 nicklas 109   /**
3663 14 Aug 07 nicklas 110     Stop all running timers
3663 14 Aug 07 nicklas 111   */
3663 14 Aug 07 nicklas 112   public void stopAll()
3663 14 Aug 07 nicklas 113   {
3663 14 Aug 07 nicklas 114     for (int i = 0; i < timers.length; ++i)
3663 14 Aug 07 nicklas 115     {
3663 14 Aug 07 nicklas 116       stop(i);
3663 14 Aug 07 nicklas 117     }
3663 14 Aug 07 nicklas 118   }
3663 14 Aug 07 nicklas 119   
3663 14 Aug 07 nicklas 120   /**
3663 14 Aug 07 nicklas 121     Check if a timer is running or not.
3663 14 Aug 07 nicklas 122     @param index The index of the timer
3663 14 Aug 07 nicklas 123     @return TRUE if the timer is running, FALSE if it has stopped
3663 14 Aug 07 nicklas 124   */
3663 14 Aug 07 nicklas 125   public boolean isRunning(int index)
3663 14 Aug 07 nicklas 126   {
3663 14 Aug 07 nicklas 127     return isRunning[index];
3663 14 Aug 07 nicklas 128   }
3663 14 Aug 07 nicklas 129   
3663 14 Aug 07 nicklas 130   /**
3663 14 Aug 07 nicklas 131     Get the current time of a timer. 
3663 14 Aug 07 nicklas 132     @param index The index of the timer
3663 14 Aug 07 nicklas 133     @return The current time of the timer
3663 14 Aug 07 nicklas 134   */
3663 14 Aug 07 nicklas 135   public long getTime(int index)
3663 14 Aug 07 nicklas 136   {
3663 14 Aug 07 nicklas 137     return timers[index] + (isRunning[index] ? System.nanoTime() : 0);
3663 14 Aug 07 nicklas 138   }
3663 14 Aug 07 nicklas 139   
3663 14 Aug 07 nicklas 140   /**
3663 14 Aug 07 nicklas 141     Reset a timer.
3663 14 Aug 07 nicklas 142     @param index The timer to reset
3663 14 Aug 07 nicklas 143   */
3663 14 Aug 07 nicklas 144   public void reset(int index)
3663 14 Aug 07 nicklas 145   {
3663 14 Aug 07 nicklas 146     timers[index] = isRunning[index] ? -System.nanoTime(): 0;
3663 14 Aug 07 nicklas 147   }
3663 14 Aug 07 nicklas 148   
3663 14 Aug 07 nicklas 149   /**
3663 14 Aug 07 nicklas 150     Reset all timers.
3663 14 Aug 07 nicklas 151   */
3663 14 Aug 07 nicklas 152   public void resetAll()
3663 14 Aug 07 nicklas 153   {
3663 14 Aug 07 nicklas 154     for (int i = 0; i < timers.length; ++i)
3663 14 Aug 07 nicklas 155     {
3663 14 Aug 07 nicklas 156       reset(i);
3663 14 Aug 07 nicklas 157     }
3663 14 Aug 07 nicklas 158   }
3663 14 Aug 07 nicklas 159   
3663 14 Aug 07 nicklas 160   /**
3663 14 Aug 07 nicklas 161     Print out time information about each timer. The times
3663 14 Aug 07 nicklas 162     are rounded to millisecond values.
3663 14 Aug 07 nicklas 163   */
6127 14 Sep 12 nicklas 164   @Override
3663 14 Aug 07 nicklas 165   public String toString()
3663 14 Aug 07 nicklas 166   {
3663 14 Aug 07 nicklas 167     StringBuilder sb = new StringBuilder();
3663 14 Aug 07 nicklas 168     for (int i = 0; i < timers.length; ++i)
3663 14 Aug 07 nicklas 169     {
3663 14 Aug 07 nicklas 170       sb.append(names[i]).append("\t").append(getTime(i) / 1000000).append(" ms");
3663 14 Aug 07 nicklas 171       if (isRunning[i])
3663 14 Aug 07 nicklas 172       {
3663 14 Aug 07 nicklas 173         sb.append(" (running)");
3663 14 Aug 07 nicklas 174       }
3663 14 Aug 07 nicklas 175       sb.append("\n");
3663 14 Aug 07 nicklas 176     }
3663 14 Aug 07 nicklas 177     return sb.toString();
3663 14 Aug 07 nicklas 178   }
3663 14 Aug 07 nicklas 179   
3663 14 Aug 07 nicklas 180 }