/* Copyright (c) 2008-2009 HomeAway, Inc.
* All rights reserved. http://www.perf4j.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.perf4j;
import java.io.Serializable;
/**
* TimingStatistics represent a set of statistical measures over a set of timing data, such as a collection of
* StopWatch instances.
*
* @author Alex Devine
*/
public class TimingStatistics implements Serializable, Cloneable {
private static final long serialVersionUID = 2854670870560621993L;
private double mean;
private double runningQ; //for keeping running standard deviation
private long max;
private long min;
private int count;
// --- Constructors ---
/**
* Default constructor allows you to set performance statistics later using the setter methods.
*/
public TimingStatistics() { }
/**
* Creates a TimingStatistics object with the specified data.
*
* @param mean The mean execution time, in ms, of the underlying time records.
* @param standardDeviation The standard deviation, in ms, of the underlying time records.
* @param max The maximum value in ms of the logged execution times.
* @param min The minimum value in ms of the logged execution times.
* @param count The total number of executions that were timed.
*/
public TimingStatistics(double mean, double standardDeviation, long max, long min, int count) {
this.mean = mean;
this.runningQ = Math.pow(standardDeviation, 2.0) * count;
this.max = max;
this.min = min;
this.count = count;
}
// --- Utility Methods ---
/**
* This method updates the calculated statistics with a new logged execution time.
*
* @param elapsedTime The elapsed time being used to update the statistics.
* @return this TimingStatistics instance
*/
public TimingStatistics addSampleTime(long elapsedTime) {
count++;
double diffFromMean = elapsedTime - mean;
mean = mean + (diffFromMean / count);
runningQ = runningQ + (((count - 1) * Math.pow(diffFromMean, 2.0)) / count);
//special case initial stopWatch when finding max and min
if (count == 1) {
min = elapsedTime;
max = elapsedTime;
} else {
if (elapsedTime < min) {
min = elapsedTime;
}
if (elapsedTime > max) {
max = elapsedTime;
}
}
return this;
}
// --- Bean Properties ---
public double getMean() {
return mean;
}
public double getStandardDeviation() {
return Math.sqrt(runningQ / count);
}
public long getMax() {
return max;
}
public long getMin() {
return min;
}
public int getCount() {
return count;
}
// --- Object Methods ---
public String toString() {
return "mean[" + getMean() +
"] stddev[" + getStandardDeviation() +
"] min[" + getMin() +
"] max[" + getMax() +
"] count[" + getCount() + "]";
}
public TimingStatistics clone() {
try {
return (TimingStatistics) super.clone();
} catch (CloneNotSupportedException cnse) {
throw new Error("Unexpected CloneNotSupportedException");
}
}
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof TimingStatistics)) {
return false;
}
TimingStatistics that = (TimingStatistics) o;
if (count != that.count) {
return false;
}
if (max != that.max) {
return false;
}
if (Double.compare(that.mean, mean) != 0) {
return false;
}
if (min != that.min) {
return false;
}
if (Double.compare(that.runningQ, runningQ) != 0) {
return false;
}
return true;
}
public int hashCode() {
int result;
long temp;
temp = mean != +0.0d ? Double.doubleToLongBits(mean) : 0L;
result = (int) (temp ^ (temp >>> 32));
temp = runningQ != +0.0d ? Double.doubleToLongBits(runningQ) : 0L;
result = 31 * result + (int) (temp ^ (temp >>> 32));
result = 31 * result + (int) (max ^ (max >>> 32));
result = 31 * result + (int) (min ^ (min >>> 32));
result = 31 * result + count;
return result;
}
}