001package org.javasimon; 002 003/** 004 * Stopwatch Simon measures time spans and holds related statistics. 005 * Methods {@link #start} creates new {@link org.javasimon.Split} object. 006 * On this object you can call {@link org.javasimon.Split#stop()} - this demarcates measured interval. 007 * Alternatively method {@link #addSplit(Split)} can be used to add split to the stopwatch ({@link Split#create(long)} 008 * can be used to create finished Split for any nanos value). Both ways effectively 009 * updates usage times, increase usage counter by one and updates total time of the stopwatch. 010 * Split object enables multiple time-splits to be measured in parallel. 011 * <p/> 012 * Example: 013 * <pre> 014 * Split split = SimonManager.getStopwatch("com.my.stopwatch").start(); 015 * //... here goes the measured code 016 * split.stop(); 017 * System.out.println("Result: " + split.getStopwatch()); // print will be probably somewhere else</pre> 018 * This can be used for simple micro-benchmarking, critical section monitoring, in web 019 * filter to measure request times, etc. 020 * 021 * {@link org.javasimon.SimonManager} should always be used to get the stopwatch before using it, 022 * because otherwise the code will not reflect enable/disable of the whole API. 023 * 024 * @author <a href="mailto:virgo47@gmail.com">Richard "Virgo" Richter</a> 025 */ 026public interface Stopwatch extends Simon { 027 /** 028 * Starts the new split for this stopwatch. This action does not hold any resources and 029 * if {@link Split} object is collected, no leak occurs. However, active count is increased 030 * and without stopping the split active count stays increased which may render that 031 * information useless. 032 * 033 * @return split object 034 * @see org.javasimon.Split#stop() 035 */ 036 Split start(); 037 038 /** 039 * Adds {@link Split} to the stopwatch which is useful for aggregation of splits created for other stopwatch. 040 * Split object should be stopped. Main difference is the callback method called as 041 * {@link org.javasimon.callback.Callback#onStopwatchAdd(Stopwatch, Split, StopwatchSample)} provides split object to the callback. 042 * <p/> 043 * Usage examples: 044 * <pre>Split split = Split.start(); // no stopwatch needed 045 * ... 046 * someStopwatch.addSplit(split.stop()); // you may omit stop(), if you does not use the split after this point</pre> 047 * 048 * @param split split object (should be stopped) 049 * @return this stopwatch 050 * @since 3.1 051 */ 052 Stopwatch addSplit(Split split); 053 054 /** 055 * Returns total sum of all split times in nanoseconds. 056 * 057 * @return total time of the stopwatch in nanoseconds 058 */ 059 long getTotal(); 060 061 /** 062 * Returns value of the last added split - whether it was added directly or with stop method. 063 * 064 * @return value of the last added split 065 */ 066 long getLast(); 067 068 /** 069 * Returns usage count of the stopwatch. Counter is increased by {@code addTime} and 070 * {@code stop} - that means that it's updated every time the next time split is added. 071 * 072 * @return count of time splits 073 */ 074 long getCounter(); 075 076 /** 077 * Returns maximal time split value in nanoseconds. 078 * 079 * @return maximal time split in nanoseconds 080 */ 081 long getMax(); 082 083 /** 084 * Returns minimal time split value in nanoseconds. 085 * 086 * @return minimal time split in nanoseconds 087 */ 088 long getMin(); 089 090 /** 091 * Returns ms timestamp when the max value was measured. 092 * 093 * @return ms timestamp of the max value measurement 094 */ 095 long getMaxTimestamp(); 096 097 /** 098 * Returns ms timestamp when the min value was measured. 099 * 100 * @return ms timestamp of the min value measurement 101 */ 102 long getMinTimestamp(); 103 104 /** 105 * Returns current number of measured splits (concurrently running). This counter can show more 106 * splits than is measured at any moment if some splits were "forgotten" (not stopped and garbage 107 * collected). This does not imply any resource leak, just bad practice of not stopping Splits somewhere 108 * in the client code. 109 * 110 * @return current number of active splits 111 */ 112 long getActive(); 113 114 /** 115 * Returns peek value of active concurrent splits. 116 * 117 * @return maximum reached value of active splits 118 */ 119 long getMaxActive(); 120 121 /** 122 * Returns ms timestamp when the last peek of the active split count occurred. 123 * 124 * @return ms timestamp of the last peek of the active split count 125 */ 126 long getMaxActiveTimestamp(); 127 128 /** 129 * Returns mean value (average) of all measured values. 130 * If {@link #getCounter()} is 0 it should return {@code Double.NaN}, but for practical reasons returns 0. 131 * 132 * @return mean value 133 */ 134 double getMean(); 135 136 /** 137 * Returns unbiased estimate of standard deviation. If {@link #getCounter()} is 0 returns {@code Double.NaN}. 138 * http://en.wikipedia.org/wiki/Unbiased_estimation_of_standard_deviation 139 * 140 * @return unbiased estimate of standard deviation 141 */ 142 double getStandardDeviation(); 143 144 /** 145 * Returns unbiased estimate of the population variance. If {@link #getCounter()} is 0 returns {@code Double.NaN}. 146 * http://en.wikipedia.org/wiki/Variance#Population_variance_and_sample_variance 147 * 148 * @return unbiased estimated variance 149 */ 150 double getVariance(); 151 152 /** 153 * Returns variance value of all measured values (entire population). 154 * If {@link #getCounter()} is 0 returns {@code Double.NaN}. 155 * http://en.wikipedia.org/wiki/Variance#Population_variance_and_sample_variance 156 * 157 * @return entire population variance 158 */ 159 double getVarianceN(); 160 161 @Override 162 StopwatchSample sample(); 163 164 StopwatchSample sampleIncrement(Object key); 165 StopwatchSample sampleIncrementNoReset(Object key); 166}