2
Copyright (C) 2002-2004 MySQL AB
4
This program is free software; you can redistribute it and/or modify
5
it under the terms of version 2 of the GNU General Public License as
6
published by the Free Software Foundation.
8
There are special exceptions to the terms and conditions of the GPL
9
as it is applied to this software. View the full text of the
10
exception in file EXCEPTIONS-CONNECTOR-J in the directory of this
11
software distribution.
13
This program is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
GNU General Public License for more details.
18
You should have received a copy of the GNU General Public License
19
along with this program; if not, write to the Free Software
20
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
package testsuite.perf;
27
import testsuite.BaseTestCase;
29
import java.text.NumberFormat;
31
import java.util.ArrayList;
32
import java.util.List;
35
* Base class for performance test cases. Handles statistics.
37
* @author Mark Matthews
39
public abstract class BasePerfTest extends BaseTestCase {
40
// ~ Static fields/initializers
41
// ---------------------------------------------
44
* Confidence interval lookup table, indexed by degrees of freedom at 95%.
46
private static final double[] T95 = { 12.706, 4.303, 3.182, 2.776, 2.571,
47
2.447, 2.365, 2.306, 2.262, 2.228, 2.201, 2.179, 2.160, 2.145,
48
2.131, 2.120, 2.110, 2.101, 2.093, 2.086, 2.080, 2.074, 2.069,
49
2.064, 2.060, 2.056, 2.052, 2.048, 2.045, 2.042 };
52
* Confidence interval lookup table, indexed by degrees of freedom at 99%.
54
private static final double[] T99 = { 63.657, 9.925, 5.841, 4.604, 4.032,
55
3.707, 3.499, 3.355, 3.250, 3.169, 3.106, 3.055, 3.012, 2.977,
56
2.947, 2.921, 2.898, 2.878, 2.861, 2.845, 2.831, 2.819, 2.807,
57
2.797, 2.787, 2.779, 2.771, 2.763, 2.756, 2.750 };
59
static NumberFormat numberFormatter = NumberFormat.getInstance();
62
numberFormatter.setMaximumFractionDigits(4);
63
numberFormatter.setMinimumFractionDigits(4);
67
// --------------------------------------------------------
70
* List of values for each iteration
72
private List testValuesList = new ArrayList();
74
private double confidenceLevel = 95; // 95% by default
76
private double confidenceValue = 0;
78
private double intervalWidth = 0.1;
80
private double meanValue = 0;
82
private double squareSumValue = 0;
84
private double sumValue = 0;
86
private double variationValue = 0;
89
* The number of iterations that we have performed
91
private int numIterations = 0;
94
// -----------------------------------------------------------
97
* Creates a new BasePerfTest object.
100
* the testcase name to perform.
102
public BasePerfTest(String name) {
107
// ----------------------------------------------------------------
110
* Returns the meanValue.
114
public double getMeanValue() {
115
return this.meanValue;
119
* Sub-classes should override this to perform the operation to be measured.
122
* if an error occurs.
124
protected abstract void doOneIteration() throws Exception;
127
* Returns the current confidence level.
129
* @return the current confindence level.
131
protected double getCurrentConfidence() {
132
return (this.intervalWidth - this.confidenceValue) * 100;
136
* Returns the current margin of error.
138
* @return the current margin of error.
140
protected double getMarginOfError() {
141
return getConfidenceLookup()
142
* (getStandardDeviationP() / Math.sqrt(this.numIterations));
146
* Returns the current STDDEV.
148
* @return the current STDDEV
150
protected double getStandardDeviationP() {
151
if (this.numIterations < 1) {
156
.sqrt(((this.numIterations * this.squareSumValue) - (this.sumValue * this.sumValue))
157
/ (this.numIterations * this.numIterations));
161
* Adds one test result to the statistics.
164
* a single result representing the value being measured in the
167
protected void addResult(double value) {
168
this.numIterations++;
169
this.testValuesList.add(new Double(value));
171
this.sumValue += value;
172
this.squareSumValue += (value * value);
173
this.meanValue = this.sumValue / this.numIterations;
174
this.variationValue = (this.squareSumValue / this.numIterations)
175
- (this.meanValue * this.meanValue);
177
// Can only have confidence when more than one test
178
// has been completed
179
if (this.numIterations > 1) {
180
this.confidenceValue = this.intervalWidth
181
- ((2.0 * getConfidenceLookup() * Math
182
.sqrt(this.variationValue
183
/ (this.numIterations - 1.0))) / this.meanValue);
188
* Calls doIteration() the <code>numIterations</code> times, displaying
189
* the mean, std, margin of error and confidence level.
191
* @param numIterations
192
* the number of iterations to perform ( < 30)
194
* if an error occurs.
196
protected void doIterations(int numIterations) throws Exception {
197
for (int i = 0; i < numIterations; i++) {
203
* Reports the current results to STDOUT, preceeded by
204
* <code>additionalMessage</code> if not null.
206
* @param additionalMessage
207
* the additional message to print, or null if no message.
209
protected synchronized void reportResults(String additionalMessage) {
210
StringBuffer messageBuf = new StringBuffer();
212
if (additionalMessage != null) {
213
messageBuf.append(additionalMessage);
214
messageBuf.append(": ");
217
messageBuf.append(" mean: ");
218
messageBuf.append(numberFormatter.format(this.meanValue));
219
messageBuf.append(" stdevp: ");
220
messageBuf.append(numberFormatter.format(getStandardDeviationP()));
221
messageBuf.append(" m-o-e: ");
222
messageBuf.append(numberFormatter.format(getMarginOfError()));
224
System.out.println(messageBuf.toString());
227
private double getConfidenceLookup() {
228
if (this.confidenceLevel == 95) {
229
return T95[this.numIterations - 1];
230
} else if (this.confidenceLevel == 99) {
231
return T99[this.numIterations - 1];
233
throw new IllegalArgumentException(
234
"Confidence level must be 95 or 99");