KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > bak > pcj > benchmark > BenchmarkRunner


1 /*
2  * Primitive Collections for Java.
3  * Copyright (C) 2003 Søren Bak
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  */

19 package bak.pcj.benchmark;
20
21 import java.lang.reflect.Method JavaDoc;
22 import java.lang.reflect.Constructor JavaDoc;
23 import java.lang.reflect.Modifier JavaDoc;
24 import java.lang.reflect.InvocationTargetException JavaDoc;
25
26 import java.io.Writer JavaDoc;
27 import java.io.FileWriter JavaDoc;
28 import java.io.IOException JavaDoc;
29
30 /**
31  * Controls the execution of benchmarks. The runner automatically
32  * discovers benchmark tasks in benchmark classes using the
33  * reflection mechanism. This procedure is inspired by the way that
34  * JUnit works.
35  *
36  * @author Søren Bak
37  * @version 1.1 2003/15/2
38  * @since 1.0
39  */

40 public class BenchmarkRunner {
41
42     /** Indicates whether verbose output should be enabled. */
43     private boolean verbose = true;
44
45     /** The report generated by this runner. */
46     private Report report;
47
48     /** The time used by the relax() method. */
49     private long relaxTime = 4000L;
50
51     /**
52      * Creates a new benchmark runner with an empty report.
53      */

54     public BenchmarkRunner() {
55         report = new Report();
56     }
57
58     /**
59      * Enables or disables verbose output to <tt>System.out</tt>.
60      * Verbose output is enabled by default.
61      *
62      * @param verbose
63      * <tt>true</tt> if verbose output should be enabled;
64      * <tt>false</tt> otherwise.
65      */

66     public void setVerbose(boolean verbose)
67     { this.verbose = verbose; }
68
69     /**
70      * Relaxes the JVM by giving it a few seconds to garbage collect
71      * and stabilize disk I/O.
72      */

73     private void relax() {
74         if (verbose)
75             System.out.println("Garbage collecting...");
76         System.gc();
77         try {
78             Thread.sleep(relaxTime);
79         } catch (InterruptedException JavaDoc e) {
80         }
81     }
82
83     private String JavaDoc nameOf(Class JavaDoc cls) {
84         String JavaDoc name = cls.getName();
85         int ldot = name.lastIndexOf('.');
86         if (ldot != -1)
87             name = name.substring(ldot+1);
88         return name;
89     }
90
91     /**
92      * Returns the report produced by this benchmark runner.
93      * Note that the returned report is mutable and can be modified
94      * before formatting.
95      *
96      * @return the report produced by this benchmark runner.
97      */

98     public Report getReport()
99     { return report; }
100
101     /**
102      * Runs a specified benchmark on a specified data set.
103      * The results are collected in the runner's report.
104      *
105      * @param bm
106      * the benchmark to run.
107      *
108      * @param dataSet
109      * the data set on which to run the benchmark.
110      *
111      * @see #getReport()
112      */

113     public void runBenchmark(Benchmark bm, DataSet dataSet) {
114         relax();
115
116         // Set up id's
117
String JavaDoc classId = bm.getClassId();
118         String JavaDoc dataSetId = dataSet.getId();
119         String JavaDoc benchmarkId = nameOf(bm.getClass());
120         String JavaDoc taskDescription = "";
121
122         if (verbose)
123             System.out.println("Running " + benchmarkId + "/" + classId + " with data " + dataSetId);
124
125         // Loop over benchmark methods
126
Method JavaDoc[] methods = bm.getClass().getMethods();
127         for (int i = 0; i < methods.length; i++) {
128             Method JavaDoc m = methods[i];
129             // Non-abstract public methods that starts with "benchmark" and has one DataSet argument
130
if ((m.getModifiers() & (Modifier.PUBLIC|Modifier.ABSTRACT)) == Modifier.PUBLIC && m.getName().startsWith("benchmark") && m.getParameterTypes().length == 1 && (DataSet.class).isAssignableFrom(m.getParameterTypes()[0]) ) {
131                 if (verbose)
132                     System.out.println(" task: " + m.getName().substring("benchmark".length()));
133                 try {
134                     taskDescription = (String JavaDoc)m.invoke(bm, new Object JavaDoc[]{dataSet});
135                 } catch (IllegalAccessException JavaDoc iae) {
136                     throw new RuntimeException JavaDoc(iae.getMessage());
137                 } catch (InvocationTargetException JavaDoc ite) {
138                     throw new RuntimeException JavaDoc(ite.getMessage());
139                 }
140                 long time = bm.readTimer();
141                 String JavaDoc taskId = m.getName().substring("benchmark".length());
142                 Result result = new Result(benchmarkId, dataSetId, classId, taskId, taskDescription, time);
143                 report.addResult(result);
144             }
145         }
146     }
147
148     private static void printUsageAndExit(Throwable JavaDoc e) {
149         System.err.println("Usage: bak.pcj.benchmark.BenchmarkRunner <dataset class> <dataset size> <benchmark class> <output file>");
150         if (e != null) {
151             System.err.println("An exception was raised:");
152             e.printStackTrace();
153         }
154         System.exit(1);
155     }
156
157     /**
158      * Runs the a benchmark from the command line.
159      * <br>The first parameter is the name of the data set class to use.
160      * <br>The second parameter is the size of the data sets to use.
161      * <br>The third parameter is the name of the benchmark class to use.
162      * <br>The fourth parameter is name of file on which to write the
163      * results.
164      *
165      * @param args
166      * as specified above.
167      */

168     public static void main(String JavaDoc[] args) {
169         int size = 0;
170         DataSet dataSet = null;
171         Benchmark benchmark = null;
172         Writer JavaDoc out = null;
173
174         // Check arguments
175
if (args.length != 4)
176             printUsageAndExit(null);
177
178         // Data set size
179
try {
180             size = Integer.parseInt(args[1]);
181             if (size <= 0)
182                 printUsageAndExit(null);
183         } catch (NumberFormatException JavaDoc e) {
184             printUsageAndExit(e);
185         }
186
187         // Data set
188
try {
189             Class JavaDoc dataSetClass = Class.forName(args[0]);
190             Constructor JavaDoc c = dataSetClass.getConstructor(new Class JavaDoc[]{Integer.TYPE});
191             dataSet = (DataSet)c.newInstance(new Object JavaDoc[]{new Integer JavaDoc(size)});
192         } catch (InstantiationException JavaDoc ie) {
193             printUsageAndExit(ie);
194         } catch (IllegalAccessException JavaDoc iae) {
195             printUsageAndExit(iae);
196         } catch (ClassNotFoundException JavaDoc cnfe) {
197             printUsageAndExit(cnfe);
198         } catch (NoSuchMethodException JavaDoc nsme) {
199             printUsageAndExit(nsme);
200         } catch (InvocationTargetException JavaDoc ite) {
201             printUsageAndExit(ite);
202         }
203
204         // Benchmark
205
try {
206             Class JavaDoc benchmarkClass = Class.forName(args[2]);
207             benchmark = (Benchmark)benchmarkClass.newInstance();
208         } catch (InstantiationException JavaDoc ie) {
209             printUsageAndExit(ie);
210         } catch (IllegalAccessException JavaDoc iae) {
211             printUsageAndExit(iae);
212         } catch (ClassNotFoundException JavaDoc cnfe) {
213             printUsageAndExit(cnfe);
214         }
215
216         // Output
217
try {
218             out = new FileWriter JavaDoc(args[3]);
219         } catch (IOException JavaDoc e) {
220             printUsageAndExit(e);
221         }
222
223         BenchmarkRunner run = new BenchmarkRunner();
224
225         // Run once to load classes and compile code
226
run.runBenchmark(benchmark, dataSet);
227         run.report.clearResults();
228
229         // Run again to collect results
230
run.runBenchmark(benchmark, dataSet);
231
232         try {
233             run.report.writeResults(out);
234             out.flush();
235             out.close();
236         } catch (IOException JavaDoc e) {
237             printUsageAndExit(e);
238         }
239     }
240
241 }
Popular Tags