Changeset 1128
- Timestamp:
- 03/18/13 12:12:42 (12 years ago)
- File:
-
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/java-utils/src/main/java/de/ugoe/cs/util/StopWatch.java
r1119 r1128 13 13 // limitations under the License. 14 14 15 package de.ugoe.cs. autoquest.tasktrees.temporalrelation;15 package de.ugoe.cs.util; 16 16 17 17 import java.io.PrintStream; … … 24 24 /** 25 25 * <p> 26 * TODO comment 26 * This is a simple implementation for a stop watch that can be used for performance measures. 27 * A stop watch can be used to measure several splits. Each split is started and stopped using the 28 * same id provided to the {@link #start(String)} and {@link #stop(String)} methods. The measured 29 * durations can be retrieved afterwards using {@link #getDuration(String)}. 30 * {@link #dumpStatistics(PrintStream)} is a convenience method useful to effectively dump all 31 * information for the different splits. 27 32 * </p> 28 33 * … … 32 37 33 38 /** 34 * 35 */ 36 private Map<String, List<Long>> mWatches = new HashMap<String, List<Long>>(); 37 38 /** 39 * the splits hold internally 40 */ 41 private Map<String, Split> mSplits = new HashMap<String, Split>(); 42 43 /** 44 * starts a split with the given id. If the split with the id is already started, an 45 * {@link IllegalStateException} is thrown. 39 46 * 47 * @param id the id of the split to be started 48 * 49 * @throws IllegalStateException if the split is already started 50 */ 51 public void start(String id) throws IllegalStateException { 52 Split split = mSplits.get(id); 53 54 if (split == null) { 55 split = new Split(id); 56 mSplits.put(id, split); 57 } 58 59 split.start(); 60 } 61 62 /** 63 * stops a split with the given id. If the split with the id is already stopped, an 64 * {@link IllegalStateException} is thrown. If no split with the given id exists, an 65 * {@link IllegalArgumentException} is thrown. 40 66 * 41 * @param id 42 * /43 public void start(String id) {44 List<Long> timeStamps = mWatches.get(id);45 46 if (timeStamps == null){47 timeStamps = new LinkedList<Long>();48 mWatches.put(id, timeStamps);49 }50 51 if (timeStamps.size() % 2 == 0) {52 timeStamps.add(System.currentTimeMillis());53 }54 else {55 throw new IllegalStateException("watch with id " + id + " already running");56 }57 }58 59 /**67 * @param id the id of the split to be stopped 68 * 69 * @throws IllegalStateException if the split is not running 70 * @throws IllegalArgumentException if the split with the given id does not exist 71 */ 72 public void stop(String id) throws IllegalStateException, IllegalArgumentException { 73 Split split = mSplits.get(id); 74 75 if (split == null) { 76 throw new IllegalArgumentException("split with id " + id + " does not exist"); 77 } 78 79 split.stop(); 80 } 81 82 /** 83 * returns the duration of a split with the given id. If the split with the id is currently 84 * running, it is stopped. If no split with the given id exists, an 85 * {@link IllegalArgumentException} is thrown. 60 86 * 61 * 62 * @param id 63 */ 64 public void stop(String id) { 65 List<Long> timeStamps = mWatches.get(id); 87 * @param id the id of the split for which the duration shall be returned 88 * 89 * @return the duration measured for the split 90 * 91 * @throws IllegalArgumentException if the split with the given id does not exist 92 */ 93 public long getDuration(String id) throws IllegalArgumentException { 94 Split split = mSplits.get(id); 95 96 if (split == null) { 97 throw new IllegalArgumentException("split with id " + id + " does not exist"); 98 } 66 99 67 if (timeStamps == null) { 68 throw new IllegalArgumentException("watch with id " + id + " does not exist"); 69 } 70 71 if (timeStamps.size() % 2 == 0) { 72 throw new IllegalStateException("watch with id " + id + " already stopped"); 73 } 74 else { 75 timeStamps.add(System.currentTimeMillis()); 76 } 77 } 78 79 /** 80 * 81 * 82 * @param id 83 */ 84 public long getDuration(String id) { 85 List<Long> timeStamps = mWatches.get(id); 86 87 if (timeStamps == null) { 88 throw new IllegalArgumentException("watch with id " + id + " does not exist"); 89 } 90 91 if (timeStamps.size() % 2 != 0) { 92 stop(id); 93 } 94 95 long result = 0; 96 for (long timeStamp : timeStamps) { 97 if (result >= 0) { 98 result -= timeStamp; 99 } 100 else { 101 result += timeStamp; 102 } 103 } 104 105 return result; 106 } 107 108 /** 109 * 110 * @param out 100 if (split.isRunning()) { 101 split.stop(); 102 } 103 104 return split.getDuration(); 105 } 106 107 /** 108 * resets the stop watch and clears all splits 109 */ 110 public void reset() { 111 mSplits.clear(); 112 } 113 114 /** 115 * dumps the statistics about the splits. Splits still running are stopped. The method checks 116 * if the longest split also covers the other splits. If so, it considers this split as a 117 * kind of overall duration and dumps the proportion of all other splits to this split in 118 * percentage. 119 * 120 * @param out the stream to dump the statistics to 111 121 */ 112 122 public void dumpStatistics(PrintStream out) { 113 if (m Watches.size() <= 0) {114 throw new IllegalStateException("no watches registered that could be dumped");123 if (mSplits.size() <= 0) { 124 throw new IllegalStateException("no splits registered that could be dumped"); 115 125 } 116 126 … … 118 128 119 129 // get durations 120 for (String id : m Watches.keySet()) {130 for (String id : mSplits.keySet()) { 121 131 durations.put(id, getDuration(id)); 122 132 } … … 145 155 // get longest duration and check whether it spans all other entries 146 156 String id = sortedIds.get(sortedIds.size() - 1); 147 List<Long> timeStamps = mWatches.get(id); 148 long firstTimeStamp = timeStamps.get(0); 149 long lastTimeStamp = timeStamps.get(timeStamps.size() - 1); 150 long longestDuration = durations.get(id); 157 Split longestWatch = mSplits.get(id); 151 158 boolean longestDurationCoversOthers = true; 152 159 153 for (Map.Entry<String, List<Long>> watch : mWatches.entrySet()) {154 if ((watch.getValue().get (0) < firstTimeStamp) ||155 (watch.getValue().get (watch.getValue().size() - 1) > lastTimeStamp))160 for (Map.Entry<String, Split> watch : mSplits.entrySet()) { 161 if ((watch.getValue().getFirstStart() < longestWatch.getFirstStart()) || 162 (watch.getValue().getLastStop() > longestWatch.getLastStop())) 156 163 { 157 164 longestDurationCoversOthers = false; … … 172 179 } 173 180 174 out.print(':'); 175 out.print(' '); 181 out.print(": "); 176 182 177 183 out.print(durations.get(sortedId)); 178 184 out.print(" ms"); 179 185 186 out.print(" ("); 187 out.print(mSplits.get(sortedId).getNoOfStarts()); 188 out.print(" starts"); 189 190 //out.print(", "); 191 //out.print(1000 * durations.get(sortedId) / mSplits.get(sortedId).getNoOfStarts()); 192 //out.print(" ms per 1000 starts"); 193 180 194 if (longestDurationCoversOthers) { 181 out.print(" (");195 out.print(", "); 182 196 out.print(DecimalFormat.getPercentInstance().format 183 ((double) durations.get(sortedId) / longestDuration)); 184 out.print(" of overall duration)"); 185 } 186 out.println(); 197 ((double) durations.get(sortedId) / longestWatch.getDuration())); 198 out.print(" of overall duration"); 199 } 200 201 out.println(')'); 187 202 } 188 203 189 204 out.println(); 190 205 } 206 207 /** 208 * internally used to store splits 209 */ 210 private static class Split { 211 212 /** 213 * the id of the split 214 */ 215 private String id; 216 217 /** 218 * the system time of the first start of the split 219 */ 220 private long firstStart = -1; 221 222 /** 223 * the system time of the last start of the split 224 */ 225 private long lastStart = -1; 226 227 /** 228 * the system time of the last stop of the split 229 */ 230 private long lastStop = -1; 231 232 /** 233 * the duration so far for the split (excluding the time since the last start) 234 */ 235 private long duration = 0; 236 237 /** 238 * the number of starts or the splits 239 */ 240 private long noOfStarts = 0; 241 242 /** 243 * initializes the split with its id 244 */ 245 private Split(String id) { 246 this.id = id; 247 } 248 249 /** 250 * starts the split if it is not already started 251 */ 252 private void start() throws IllegalStateException { 253 if (lastStart > -1) { 254 throw new IllegalStateException("split with id " + id + " already running"); 255 } 256 257 lastStart = System.currentTimeMillis(); 258 259 if (firstStart < 0) { 260 firstStart = lastStart; 261 } 262 263 noOfStarts++; 264 } 265 266 /** 267 * checks if the split is currently running 268 */ 269 private boolean isRunning() { 270 return (lastStart > -1); 271 } 272 273 /** 274 * stops the split if it is not already stopped 275 */ 276 private void stop() throws IllegalStateException { 277 if (lastStart < 0) { 278 throw new IllegalStateException("split with id " + id + " not running"); 279 } 280 281 lastStop = System.currentTimeMillis(); 282 duration += lastStop - lastStart; 283 lastStart = -1; 284 } 285 286 /** 287 * returns the fist start of the split 288 */ 289 private long getFirstStart() { 290 return firstStart; 291 } 292 293 /** 294 * returns the last stop of the split 295 */ 296 private long getLastStop() { 297 return lastStop; 298 } 299 300 /** 301 * returns the duration of the split measured so far excluding the time since the last 302 * start if the split is currently started 303 */ 304 private long getDuration() { 305 return duration; 306 } 307 308 /** 309 * returns the number of starts for the split 310 */ 311 private long getNoOfStarts() { 312 return noOfStarts; 313 } 314 } 191 315 }
Note: See TracChangeset
for help on using the changeset viewer.