import static java.util.concurrent.TimeUnit.NANOSECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
+import com.google.common.util.concurrent.AtomicDouble;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
-import com.google.common.util.concurrent.AtomicDouble;
-
/**
* Class that calculates and tracks time duration statistics.
*
*/
public class DurationStatsTracker {
+ private static final DecimalFormat decimalFormat;
+
private final AtomicLong totalDurations = new AtomicLong();
private final AtomicLong longestDuration = new AtomicLong();
private volatile long timeOfLongestDuration;
private volatile long timeOfShortestDuration;
private final AtomicDouble averageDuration = new AtomicDouble();
+ static {
+ final DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance();
+ symbols.setDecimalSeparator('.');
+ decimalFormat = new DecimalFormat("0.00", symbols);
+ }
+
/**
* Add a duration to track.
*
- * @param duration the duration in nanoseconds.
+ * @param duration
+ * the duration in nanoseconds.
*/
public void addDuration(long duration) {
long newTotal = currentTotal + 1;
// Calculate moving cumulative average.
- double newAve = currentAve * (double)currentTotal / (double)newTotal + (double)duration / (double)newTotal;
+ double newAve = currentAve * currentTotal / newTotal + (double) duration / (double) newTotal;
averageDuration.compareAndSet(currentAve, newAve);
totalDurations.compareAndSet(currentTotal, newTotal);
long longest = longestDuration.get();
- if( duration > longest ) {
- if(longestDuration.compareAndSet( longest, duration )) {
+ if (duration > longest) {
+ if (longestDuration.compareAndSet(longest, duration)) {
timeOfLongestDuration = System.currentTimeMillis();
}
}
long shortest = shortestDuration.get();
- if( duration < shortest ) {
- if(shortestDuration.compareAndSet( shortest, duration )) {
+ if (duration < shortest) {
+ if (shortestDuration.compareAndSet(shortest, duration)) {
timeOfShortestDuration = System.currentTimeMillis();
}
}
}
/**
- * Returns the average duration as a displayable String with units, e.g. "12.34 ms".
+ * Returns the average duration as a displayable String with units, e.g.
+ * "12.34 ms".
*/
public String getDisplayableAverageDuration() {
return formatDuration(getAverageDuration(), 0);
}
/**
- * Returns the shortest duration as a displayable String with units and the date/time at
- * which it occurred, e.g. "12.34 ms at 08/02/2014 12:30:24".
+ * Returns the shortest duration as a displayable String with units and the
+ * date/time at which it occurred, e.g. "12.34 ms at 08/02/2014 12:30:24".
*/
public String getDisplayableShortestDuration() {
return formatDuration(getShortestDuration(), getTimeOfShortestDuration());
}
/**
- * Returns the longest duration as a displayable String with units and the date/time at
- * which it occurred, e.g. "12.34 ms at 08/02/2014 12:30:24".
+ * Returns the longest duration as a displayable String with units and the
+ * date/time at which it occurred, e.g. "12.34 ms at 08/02/2014 12:30:24".
*/
public String getDisplayableLongestDuration() {
return formatDuration(getLongestDuration(), getTimeOfLongestDuration());
}
+ /**
+ * Returns formatted value of number, e.g. "12.34". Always is used dot as
+ * decimal separator.
+ */
+ private static synchronized String formatDecimalValue(double value) {
+ return decimalFormat.format(value);
+ }
+
private String formatDuration(double duration, long timeStamp) {
- TimeUnit unit = chooseUnit((long)duration);
+ TimeUnit unit = chooseUnit((long) duration);
double value = duration / NANOSECONDS.convert(1, unit);
- return timeStamp > 0 ?
- String.format("%.4g %s at %3$tD %3$tT", value, abbreviate(unit), new Date(timeStamp)) :
- String.format("%.4g %s", value, abbreviate(unit));
+
+ return timeStamp > 0 ? String.format("%s %s at %3$tD %3$tT", formatDecimalValue(value), abbreviate(unit),
+ new Date(timeStamp)) : String.format("%s %s", formatDecimalValue(value), abbreviate(unit));
}
private static TimeUnit chooseUnit(long nanos) {
- if(SECONDS.convert(nanos, NANOSECONDS) > 0) {
+ if (SECONDS.convert(nanos, NANOSECONDS) > 0) {
return SECONDS;
}
- if(MILLISECONDS.convert(nanos, NANOSECONDS) > 0) {
+ if (MILLISECONDS.convert(nanos, NANOSECONDS) > 0) {
return MILLISECONDS;
}
- if(MICROSECONDS.convert(nanos, NANOSECONDS) > 0) {
+ if (MICROSECONDS.convert(nanos, NANOSECONDS) > 0) {
return MICROSECONDS;
}
}
private static String abbreviate(TimeUnit unit) {
- switch(unit) {
- case NANOSECONDS:
- return "ns";
- case MICROSECONDS:
- return "\u03bcs"; // μs
- case MILLISECONDS:
- return "ms";
- case SECONDS:
- return "s";
- default:
- return "";
+ switch (unit) {
+ case NANOSECONDS:
+ return "ns";
+ case MICROSECONDS:
+ return "\u03bcs"; // μs
+ case MILLISECONDS:
+ return "ms";
+ case SECONDS:
+ return "s";
+ default:
+ return "";
}
}
}