KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > util > StopWatch


1 /*
2  * Copyright 2002-2007 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.springframework.util;
18
19 import java.text.NumberFormat JavaDoc;
20 import java.util.LinkedList JavaDoc;
21 import java.util.List JavaDoc;
22
23 /**
24  * Simple stop watch, allowing for timing of a number of tasks,
25  * exposing total running time and running time for each named task.
26  *
27  * <p>Conceals use of <code>System.currentTimeMillis()</code>, improving the
28  * readability of application code and reducing the likelihood of calculation errors.
29  *
30  * <p>Note that this object is not designed to be thread-safe and does not
31  * use synchronization.
32  *
33  * <p>This class is normally used to verify performance during proof-of-concepts
34  * and in development, rather than as part of production applications.
35  *
36  * @author Rod Johnson
37  * @author Juergen Hoeller
38  * @since May 2, 2001
39  */

40 public class StopWatch {
41
42     /**
43      * Identifier of this stop watch.
44      * Handy when we have output from multiple stop watches
45      * and need to distinguish between them in log or console output.
46      */

47     private final String JavaDoc id;
48
49     private boolean keepTaskList = true;
50
51     /** List of TaskInfo objects */
52     private final List JavaDoc taskList = new LinkedList JavaDoc();
53
54     /** Start time of the current task */
55     private long startTimeMillis;
56
57     /** Is the stop watch currently running? */
58     private boolean running;
59
60     /** Name of the current task */
61     private String JavaDoc currentTaskName;
62
63     private TaskInfo lastTaskInfo;
64
65     private int taskCount;
66
67     /** Total running time */
68     private long totalTimeMillis;
69
70
71     /**
72      * Construct a new stop watch. Does not start any task.
73      */

74     public StopWatch() {
75         this.id = "";
76     }
77
78     /**
79      * Construct a new stop watch with the given id.
80      * Does not start any task.
81      * @param id identifier for this stop watch.
82      * Handy when we have output from multiple stop watches
83      * and need to distinguish between them.
84      */

85     public StopWatch(String JavaDoc id) {
86         this.id = id;
87     }
88
89     /**
90      * Determine whether the TaskInfo array is built over time. Set this to
91      * "false" when using a StopWatch for millions of intervals, or the task
92      * info structure will consume excessive memory. Default is "true".
93      */

94     public void setKeepTaskList(boolean keepTaskList) {
95         this.keepTaskList = keepTaskList;
96     }
97
98
99     /**
100      * Start an unnamed task. The results are undefined if {@link #stop()}
101      * or timing methods are called without invoking this method.
102      * @see #stop()
103      */

104     public void start() throws IllegalStateException JavaDoc {
105         start("");
106     }
107
108     /**
109      * Start a named task. The results are undefined if {@link #stop()}
110      * or timing methods are called without invoking this method.
111      * @param taskName the name of the task to start
112      * @see #stop()
113      */

114     public void start(String JavaDoc taskName) throws IllegalStateException JavaDoc {
115         if (this.running) {
116             throw new IllegalStateException JavaDoc("Can't start StopWatch: it's already running");
117         }
118         this.startTimeMillis = System.currentTimeMillis();
119         this.running = true;
120         this.currentTaskName = taskName;
121     }
122
123     /**
124      * Stop the current task. The results are undefined if timing
125      * methods are called without invoking at least one pair
126      * {@link #start()} / {@link #stop()} methods.
127      * @see #start()
128      */

129     public void stop() throws IllegalStateException JavaDoc {
130         if (!this.running) {
131             throw new IllegalStateException JavaDoc("Can't stop StopWatch: it's not running");
132         }
133         long lastTime = System.currentTimeMillis() - this.startTimeMillis;
134         this.totalTimeMillis += lastTime;
135         this.lastTaskInfo = new TaskInfo(this.currentTaskName, lastTime);
136         if (this.keepTaskList) {
137             this.taskList.add(lastTaskInfo);
138         }
139         ++this.taskCount;
140         this.running = false;
141         this.currentTaskName = null;
142     }
143
144     /**
145      * Return whether the stop watch is currently running.
146      */

147     public boolean isRunning() {
148         return this.running;
149     }
150
151
152     /**
153      * Return the time taken by the last task.
154      */

155     public long getLastTaskTimeMillis() throws IllegalStateException JavaDoc {
156         if (this.lastTaskInfo == null) {
157             throw new IllegalStateException JavaDoc("No tests run: can't get last interval");
158         }
159         return this.lastTaskInfo.getTimeMillis();
160     }
161
162     /**
163      * Return the total time in milliseconds for all tasks.
164      */

165     public long getTotalTimeMillis() {
166         return totalTimeMillis;
167     }
168
169     /**
170      * Return the total time in seconds for all tasks.
171      */

172     public double getTotalTimeSeconds() {
173         return totalTimeMillis / 1000.0;
174     }
175
176     /**
177      * Return the number of tasks timed.
178      */

179     public int getTaskCount() {
180         return taskCount;
181     }
182
183     /**
184      * Return an array of the data for tasks performed.
185      */

186     public TaskInfo[] getTaskInfo() {
187         if (!this.keepTaskList) {
188             throw new UnsupportedOperationException JavaDoc("Task info is not being kept!");
189         }
190         return (TaskInfo[]) this.taskList.toArray(new TaskInfo[this.taskList.size()]);
191     }
192
193
194     /**
195      * Return a short description of the total running time.
196      */

197     public String JavaDoc shortSummary() {
198         return "StopWatch '" + this.id + "': running time (millis) = " + getTotalTimeMillis();
199     }
200
201     /**
202      * Return a string with a table describing all tasks performed.
203      * For custom reporting, call getTaskInfo() and use the task info directly.
204      */

205     public String JavaDoc prettyPrint() {
206         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(shortSummary());
207         sb.append('\n');
208         if (!this.keepTaskList) {
209             sb.append("No task info kept");
210         }
211         else {
212             TaskInfo[] tasks = getTaskInfo();
213             sb.append("-----------------------------------------\n");
214             sb.append("ms % Task name\n");
215             sb.append("-----------------------------------------\n");
216             NumberFormat JavaDoc nf = NumberFormat.getNumberInstance();
217             nf.setMinimumIntegerDigits(5);
218             nf.setGroupingUsed(false);
219             NumberFormat JavaDoc pf = NumberFormat.getPercentInstance();
220             pf.setMinimumIntegerDigits(3);
221             pf.setGroupingUsed(false);
222             for (int i = 0; i < tasks.length; i++) {
223                 sb.append(nf.format(tasks[i].getTimeMillis()) + " ");
224                 sb.append(pf.format(tasks[i].getTimeSeconds() / getTotalTimeSeconds()) + " ");
225                 sb.append(tasks[i].getTaskName() + "\n");
226             }
227         }
228         return sb.toString();
229     }
230
231     /**
232      * Return an informative string describing all tasks performed
233      * For custom reporting, call <code>getTaskInfo()</code> and use the task info directly.
234      */

235     public String JavaDoc toString() {
236         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(shortSummary());
237         if (this.keepTaskList) {
238             TaskInfo[] tasks = getTaskInfo();
239             for (int i = 0; i < tasks.length; i++) {
240                 sb.append("; [" + tasks[i].getTaskName() + "] took " + tasks[i].getTimeMillis());
241                 long percent = Math.round((100.0 * tasks[i].getTimeSeconds()) / getTotalTimeSeconds());
242                 sb.append(" = " + percent + "%");
243             }
244         }
245         else {
246             sb.append("; no task info kept");
247         }
248         return sb.toString();
249     }
250
251
252     /**
253      * Inner class to hold data about one task executed within the stop watch.
254      */

255     public static class TaskInfo {
256
257         private final String JavaDoc taskName;
258
259         private final long timeMillis;
260
261         private TaskInfo(String JavaDoc taskName, long timeMillis) {
262             this.taskName = taskName;
263             this.timeMillis = timeMillis;
264         }
265
266         /**
267          * Return the name of this task.
268          */

269         public String JavaDoc getTaskName() {
270             return taskName;
271         }
272
273         /**
274          * Return the time in milliseconds this task took.
275          */

276         public long getTimeMillis() {
277             return timeMillis;
278         }
279
280         /**
281          * Return the time in seconds this task took.
282          */

283         public double getTimeSeconds() {
284             return timeMillis / 1000.0;
285         }
286     }
287
288 }
289
Popular Tags