001package org.javasimon.callback.timeline; 002 003import org.javasimon.utils.SimonUtils; 004 005/** 006 * Stopwatch statistics gathered for a specific time range. 007 * This class is not intended to be thread safe. 008 * 009 * @author gerald 010 */ 011public class StopwatchTimeRange extends TimeRange { 012 013 /** Last value. */ 014 private long last; 015 016 /** Minimum value. */ 017 private long min = Long.MAX_VALUE; 018 019 /** Maximum value. */ 020 private long max = Long.MIN_VALUE; 021 022 /** Total sum of all values. */ 023 private long total; 024 025 /** Sum of squares. */ 026 private long squareTotal; 027 028 /** Counter - number of values. */ 029 private long counter; 030 031 /** Main constructor. */ 032 public StopwatchTimeRange(long startTimestamp, long endTimestamp) { 033 super(startTimestamp, endTimestamp); 034 } 035 036 /** 037 * Add stopwatch split information. 038 * 039 * @param timestampInMs when the split started, expressed in milliseconds 040 * @param durationInNs how long the split was, expressed in nanoseconds 041 */ 042 public void addSplit(long timestampInMs, long durationInNs) { 043 last = durationInNs; 044 total += durationInNs; 045 squareTotal += durationInNs * durationInNs; 046 if (durationInNs > max) { 047 max = durationInNs; 048 } 049 if (durationInNs < min) { 050 min = durationInNs; 051 } 052 counter++; 053 lastTimestamp = timestampInMs; 054 } 055 056 public long getLast() { 057 return last; 058 } 059 060 public long getMin() { 061 return min; 062 } 063 064 public long getMax() { 065 return max; 066 } 067 068 public long getTotal() { 069 return total; 070 } 071 072 public long getCounter() { 073 return counter; 074 } 075 076 /** Computes mean (average) using total and non-zero counter. */ 077 private double computeMean() { 078 return ((double) total) / counter; 079 } 080 081 /** 082 * Compute mean (average) duration. 083 * 084 * @return mean (average) duration. 085 */ 086 public Double getMean() { 087 return counter == 0 ? Double.NaN : computeMean(); 088 } 089 090 /** 091 * Compute variance. 092 * 093 * @return variance 094 */ 095 public Double getVariance() { 096 if (counter == 0) { 097 return Double.NaN; 098 } else { 099 final double mean = computeMean(); 100 final double meanSquare = mean * mean; 101 final double squareMean = ((double) squareTotal) / counter; 102 return squareMean - meanSquare; 103 } 104 } 105 106 /** 107 * Computes standard deviation. 108 * 109 * @return standard deviation 110 */ 111 public Double getStandardDeviation() { 112 return Math.sqrt(getVariance()); 113 } 114 115 @Override 116 protected StringBuilder toStringBuilder(StringBuilder stringBuilder) { 117 return super.toStringBuilder(stringBuilder) 118 .append(" counter=").append(counter) 119 .append(" total=").append(SimonUtils.presentNanoTime(total)) 120 .append(" min=").append(SimonUtils.presentNanoTime(min)) 121 .append(" mean=").append(SimonUtils.presentNanoTime(getMean())) 122 .append(" last=").append(SimonUtils.presentNanoTime(getLast())) 123 .append(" max=").append(SimonUtils.presentNanoTime(max)) 124 .append(" stddev=").append(SimonUtils.presentNanoTime(getStandardDeviation())); 125 } 126}