blob: 223ad141691e7a1cc8cd179b691cdcfd2d6b4142 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 */
23
24/*
25 * This is not a regression test, but a micro-benchmark.
26 *
27 * I have run this as follows:
28 *
29 * repeat 5 for f in -client -server; do mergeBench dolphin . jr -dsa -da $f TypeCheckMicroBenchmark.java; done
30 *
31 *
32 * @author Martin Buchholz
33 */
34
35import java.util.*;
36
37public class TypeCheckMicroBenchmark {
38 abstract static class Job {
39 private final String name;
40 Job(String name) { this.name = name; }
41 String name() { return name; }
42 abstract void work() throws Throwable;
43 }
44
45 private static void collectAllGarbage() {
46 final java.util.concurrent.CountDownLatch drained
47 = new java.util.concurrent.CountDownLatch(1);
48 try {
49 System.gc(); // enqueue finalizable objects
50 new Object() { protected void finalize() {
51 drained.countDown(); }};
52 System.gc(); // enqueue detector
53 drained.await(); // wait for finalizer queue to drain
54 System.gc(); // cleanup finalized objects
55 } catch (InterruptedException e) { throw new Error(e); }
56 }
57
58 /**
59 * Runs each job for long enough that all the runtime compilers
60 * have had plenty of time to warm up, i.e. get around to
61 * compiling everything worth compiling.
62 * Returns array of average times per job per run.
63 */
64 private static long[] time0(Job ... jobs) throws Throwable {
65 final long warmupNanos = 10L * 1000L * 1000L * 1000L;
66 long[] nanoss = new long[jobs.length];
67 for (int i = 0; i < jobs.length; i++) {
68 collectAllGarbage();
69 long t0 = System.nanoTime();
70 long t;
71 int j = 0;
72 do { jobs[i].work(); j++; }
73 while ((t = System.nanoTime() - t0) < warmupNanos);
74 nanoss[i] = t/j;
75 }
76 return nanoss;
77 }
78
79 private static void time(Job ... jobs) throws Throwable {
80
81 long[] warmup = time0(jobs); // Warm up run
82 long[] nanoss = time0(jobs); // Real timing run
83 long[] milliss = new long[jobs.length];
84 double[] ratios = new double[jobs.length];
85
86 final String nameHeader = "Method";
87 final String millisHeader = "Millis";
88 final String ratioHeader = "Ratio";
89
90 int nameWidth = nameHeader.length();
91 int millisWidth = millisHeader.length();
92 int ratioWidth = ratioHeader.length();
93
94 for (int i = 0; i < jobs.length; i++) {
95 nameWidth = Math.max(nameWidth, jobs[i].name().length());
96
97 milliss[i] = nanoss[i]/(1000L * 1000L);
98 millisWidth = Math.max(millisWidth,
99 String.format("%d", milliss[i]).length());
100
101 ratios[i] = (double) nanoss[i] / (double) nanoss[0];
102 ratioWidth = Math.max(ratioWidth,
103 String.format("%.3f", ratios[i]).length());
104 }
105
106 String format = String.format("%%-%ds %%%dd %%%d.3f%%n",
107 nameWidth, millisWidth, ratioWidth);
108 String headerFormat = String.format("%%-%ds %%%ds %%%ds%%n",
109 nameWidth, millisWidth, ratioWidth);
110 System.out.printf(headerFormat, "Method", "Millis", "Ratio");
111
112 // Print out absolute and relative times, calibrated against first job
113 for (int i = 0; i < jobs.length; i++)
114 System.out.printf(format, jobs[i].name(), milliss[i], ratios[i]);
115 }
116
117 private static String keywordValue(String[] args, String keyword) {
118 for (String arg : args)
119 if (arg.startsWith(keyword))
120 return arg.substring(keyword.length() + 1);
121 return null;
122 }
123
124 private static int intArg(String[] args, String keyword, int defaultValue) {
125 String val = keywordValue(args, keyword);
126 return val == null ? defaultValue : Integer.parseInt(val);
127 }
128
129 private static java.util.regex.Pattern patternArg(String[] args,
130 String keyword) {
131 String val = keywordValue(args, keyword);
132 return val == null ? null : java.util.regex.Pattern.compile(val);
133 }
134
135 private static Job[] filter(java.util.regex.Pattern filter,
136 Job[] jobs) {
137 if (filter == null) return jobs;
138 Job[] newJobs = new Job[jobs.length];
139 int n = 0;
140 for (Job job : jobs)
141 if (filter.matcher(job.name()).find())
142 newJobs[n++] = job;
143 // Arrays.copyOf not available in JDK 5
144 Job[] ret = new Job[n];
145 System.arraycopy(newJobs, 0, ret, 0, n);
146 return ret;
147 }
148
149 /**
150 * Usage: [iterations=N] [size=N] [filter=REGEXP]
151 */
152 public static void main(String[] args) throws Throwable {
153 final int iterations = intArg(args, "iterations", 30000);
154 final int size = intArg(args, "size", 1000);
155 final java.util.regex.Pattern filter
156 = patternArg(args, "filter");
157
158 final List<Integer> list = new ArrayList<Integer>();
159 final Random rnd = new Random();
160 for (int i = 0; i < size; i++)
161 list.add(rnd.nextInt());
162 final Class klazz = Integer.class;
163
164 final Job[] jobs = {
165 new Job("toArray(T[])") { void work() {
166 Object[] a = new Integer[0];
167 for (int i = 0; i < iterations; i++) {
168 try { list.toArray(a); }
169 catch (ArrayStoreException ase) {
170 throw new ClassCastException(); }}}},
171 new Job("isInstance") { void work() {
172 for (int i = 0; i < iterations; i++) {
173 for (Object x : list.toArray())
174 if (! (x != null && klazz.isInstance(x)))
175 throw new ClassCastException(); }}},
176 new Job("Class.cast") { void work() {
177 for (int i = 0; i < iterations; i++) {
178 for (Object x : list.toArray())
179 klazz.cast(x); }}},
180 new Job("write into array") { void work() {
181 Object[] a = new Integer[1];
182 for (int i = 0; i < iterations; i++) {
183 for (Object x : list.toArray()) {
184 try { a[0] = x; }
185 catch (ArrayStoreException _) {
186 throw new ClassCastException(); }}}}},
187 new Job("write into dynamic array") { void work() {
188 for (int i = 0; i < iterations; i++) {
189 for (Object x : list.toArray()) {
190 Object[] a = (Object[])
191 java.lang.reflect.Array.newInstance(klazz, 1);
192 try { a[0] = x; }
193 catch (ArrayStoreException _) {
194 throw new ClassCastException(); }}}}}
195 };
196
197 time(filter(filter, jobs));
198 }
199}