001: /***
002: * ASM Guide
003: * Copyright (c) 2007 Eric Bruneton
004: * All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: * 1. Redistributions of source code must retain the above copyright
010: * notice, this list of conditions and the following disclaimer.
011: * 2. Redistributions in binary form must reproduce the above copyright
012: * notice, this list of conditions and the following disclaimer in the
013: * documentation and/or other materials provided with the distribution.
014: * 3. Neither the name of the copyright holders nor the names of its
015: * contributors may be used to endorse or promote products derived from
016: * this software without specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
021: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
022: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
023: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
024: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
025: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
026: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
027: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
028: * THE POSSIBILITY OF SUCH DAMAGE.
029: */package app.sec2;
030:
031: import java.io.InputStream;
032: import java.util.ArrayList;
033: import java.util.Enumeration;
034: import java.util.Iterator;
035: import java.util.List;
036: import java.util.zip.ZipEntry;
037: import java.util.zip.ZipFile;
038:
039: import org.objectweb.asm.ClassAdapter;
040: import org.objectweb.asm.ClassReader;
041: import org.objectweb.asm.ClassVisitor;
042: import org.objectweb.asm.ClassWriter;
043: import org.objectweb.asm.MethodVisitor;
044: import org.objectweb.asm.commons.EmptyVisitor;
045: import org.objectweb.asm.tree.ClassNode;
046: import org.objectweb.asm.tree.MethodNode;
047: import org.objectweb.asm.tree.analysis.Analyzer;
048: import org.objectweb.asm.tree.analysis.BasicInterpreter;
049: import org.objectweb.asm.tree.analysis.SimpleVerifier;
050:
051: import ch3.sec2.AddTimerAdapter;
052: import ch3.sec2.RemoveGetFieldPutFieldAdapter;
053: import ch6.sec1.AddTimerTransformer;
054: import ch6.sec1.RemoveGetFieldPutFieldTransformer;
055:
056: /**
057: * ASM Guide example class.
058: *
059: * @author Eric Bruneton
060: */
061: public class Performances {
062:
063: public static void main(String[] args) throws Exception {
064: ZipFile zip = new ZipFile(args[0]);
065: String clazz = args.length > 1 ? args[1] : null;
066:
067: List classes = new ArrayList();
068: Enumeration entries = zip.entries();
069: while (entries.hasMoreElements()) {
070: ZipEntry e = (ZipEntry) entries.nextElement();
071: String s = e.getName();
072: if (s.endsWith(".class")) {
073: s = s.substring(0, s.length() - 6).replace('/', '.');
074: if (clazz == null || s.indexOf(clazz) != -1) {
075: InputStream is = zip.getInputStream(e);
076: classes.add(new ClassReader(is).b);
077: }
078: }
079: }
080:
081: long[] times = new long[15];
082: for (int i = 0; i < times.length; ++i) {
083: times[i] = Long.MAX_VALUE;
084: }
085:
086: for (int i = 0; i < 10; ++i) {
087: long t = System.currentTimeMillis();
088: for (int j = 0; j < classes.size(); ++j) {
089: byte[] b = (byte[]) classes.get(j);
090: new ClassReader(b).accept(new EmptyVisitor(), 0);
091: }
092: t = System.currentTimeMillis() - t;
093: times[0] = Math.min(t, times[0]);
094: System.out.println("Time to deserialize " + classes.size()
095: + " classes = " + t + " ms");
096: }
097:
098: for (int i = 0; i < 10; ++i) {
099: long t = System.currentTimeMillis();
100: for (int j = 0; j < classes.size(); ++j) {
101: byte[] b = (byte[]) classes.get(j);
102: ClassWriter cw = new ClassWriter(0);
103: new ClassReader(b).accept(cw, 0);
104: cw.toByteArray();
105: }
106: t = System.currentTimeMillis() - t;
107: times[1] = Math.min(t, times[1]);
108: System.out.println("Time to deserialize and reserialize "
109: + classes.size() + " classes = " + t + " ms");
110: }
111:
112: for (int i = 0; i < 10; ++i) {
113: long t = System.currentTimeMillis();
114: for (int j = 0; j < classes.size(); ++j) {
115: byte[] b = (byte[]) classes.get(j);
116: ClassReader cr = new ClassReader(b);
117: ClassWriter cw = new ClassWriter(cr, 0);
118: cr.accept(cw, 0);
119: cw.toByteArray();
120: }
121: t = System.currentTimeMillis() - t;
122: times[2] = Math.min(t, times[2]);
123: System.out.println("Time to deserialize and reserialize "
124: + classes.size() + " classes with copyPool = " + t
125: + " ms");
126: }
127:
128: for (int i = 0; i < 10; ++i) {
129: long t = System.currentTimeMillis();
130: for (int j = 0; j < classes.size(); ++j) {
131: byte[] b = (byte[]) classes.get(j);
132: ClassWriter cw = new ClassWriter(0);
133: ClassVisitor cv = new AddTimerAdapter(cw);
134: new ClassReader(b).accept(cv, 0);
135: cw.toByteArray();
136: }
137: t = System.currentTimeMillis() - t;
138: times[3] = Math.min(t, times[3]);
139: System.out.println("Time to deserialize and reserialize "
140: + classes.size()
141: + " classes with AddTimerAdapter = " + t + " ms");
142: }
143:
144: for (int i = 0; i < 10; ++i) {
145: long t = System.currentTimeMillis();
146: for (int j = 0; j < classes.size(); ++j) {
147: byte[] b = (byte[]) classes.get(j);
148: ClassReader cr = new ClassReader(b);
149: ClassWriter cw = new ClassWriter(cr, 0);
150: ClassVisitor cv = new AddTimerAdapter(cw);
151: cr.accept(cv, 0);
152: cw.toByteArray();
153: }
154: t = System.currentTimeMillis() - t;
155: times[4] = Math.min(t, times[4]);
156: System.out.println("Time to deserialize and reserialize "
157: + classes.size()
158: + " classes with AddTimerAdapter and copyPool = "
159: + t + " ms");
160: }
161:
162: for (int i = 0; i < 10; ++i) {
163: long t = System.currentTimeMillis();
164: for (int j = 0; j < classes.size(); ++j) {
165: byte[] b = (byte[]) classes.get(j);
166: ClassWriter cw = new ClassWriter(0);
167: ClassVisitor cv = new ClassAdapter(cw) {
168: public MethodVisitor visitMethod(int access,
169: String name, String desc, String signature,
170: String[] exceptions) {
171: return new RemoveGetFieldPutFieldAdapter(cv
172: .visitMethod(access, name, desc,
173: signature, exceptions));
174: }
175: };
176: new ClassReader(b).accept(cv, 0);
177: cw.toByteArray();
178: }
179: t = System.currentTimeMillis() - t;
180: times[5] = Math.min(t, times[5]);
181: System.out.println("Time to deserialize and reserialize "
182: + classes.size()
183: + " classes with RemoveGetFieldPutFieldAdapter = "
184: + t + " ms");
185: }
186:
187: for (int i = 0; i < 10; ++i) {
188: long t = System.currentTimeMillis();
189: for (int j = 0; j < classes.size(); ++j) {
190: byte[] b = (byte[]) classes.get(j);
191: ClassReader cr = new ClassReader(b);
192: ClassWriter cw = new ClassWriter(cr, 0);
193: ClassVisitor cv = new ClassAdapter(cw) {
194: public MethodVisitor visitMethod(int access,
195: String name, String desc, String signature,
196: String[] exceptions) {
197: return new RemoveGetFieldPutFieldAdapter(cv
198: .visitMethod(access, name, desc,
199: signature, exceptions));
200: }
201: };
202: cr.accept(cv, 0);
203: cw.toByteArray();
204: }
205: t = System.currentTimeMillis() - t;
206: times[6] = Math.min(t, times[6]);
207: System.out
208: .println("Time to deserialize and reserialize "
209: + classes.size()
210: + " classes with RemoveGetFieldPutFieldAdapter and copyPool = "
211: + t + " ms");
212: }
213:
214: for (int i = 0; i < 10; ++i) {
215: long t = System.currentTimeMillis();
216: for (int j = 0; j < classes.size(); ++j) {
217: byte[] b = (byte[]) classes.get(j);
218: ClassWriter cw = new ClassWriter(
219: ClassWriter.COMPUTE_MAXS);
220: new ClassReader(b).accept(cw, 0);
221: cw.toByteArray();
222: }
223: t = System.currentTimeMillis() - t;
224: times[7] = Math.min(t, times[7]);
225: System.out.println("Time to deserialize and reserialize "
226: + classes.size() + " classes with computeMaxs = "
227: + t + " ms");
228: }
229:
230: for (int i = 0; i < 10; ++i) {
231: int errors = 0;
232: long t = System.currentTimeMillis();
233: for (int j = 0; j < classes.size(); ++j) {
234: byte[] b = (byte[]) classes.get(j);
235: ClassWriter cw = new ClassWriter(
236: ClassWriter.COMPUTE_FRAMES);
237: try {
238: new ClassReader(b).accept(cw, 0);
239: } catch (Throwable e) {
240: ++errors;
241: }
242: cw.toByteArray();
243: }
244: t = System.currentTimeMillis() - t;
245: times[8] = Math.min(t, times[8]);
246: System.out.println("Time to deserialize and reserialize "
247: + classes.size() + " classes with computeFrames = "
248: + t + " ms (" + errors + " errors)");
249: }
250:
251: System.out.println();
252:
253: for (int i = 0; i < 10; ++i) {
254: long t = System.currentTimeMillis();
255: for (int j = 0; j < classes.size(); ++j) {
256: byte[] b = (byte[]) classes.get(j);
257: new ClassReader(b).accept(new ClassNode(), 0);
258: }
259: t = System.currentTimeMillis() - t;
260: times[9] = Math.min(t, times[9]);
261: System.out.println("Time to deserialize " + classes.size()
262: + " classes with tree package = " + t + " ms");
263: }
264:
265: for (int i = 0; i < 10; ++i) {
266: long t = System.currentTimeMillis();
267: for (int j = 0; j < classes.size(); ++j) {
268: byte[] b = (byte[]) classes.get(j);
269: ClassWriter cw = new ClassWriter(0);
270: ClassNode cn = new ClassNode();
271: new ClassReader(b).accept(cn, 0);
272: cn.accept(cw);
273: cw.toByteArray();
274: }
275: t = System.currentTimeMillis() - t;
276: times[10] = Math.min(t, times[10]);
277: System.out.println("Time to deserialize and reserialize "
278: + classes.size() + " classes with tree package = "
279: + t + " ms");
280: }
281:
282: for (int i = 0; i < 10; ++i) {
283: long t = System.currentTimeMillis();
284: for (int j = 0; j < classes.size(); ++j) {
285: byte[] b = (byte[]) classes.get(j);
286: ClassWriter cw = new ClassWriter(0);
287: ClassNode cn = new ClassNode();
288: new ClassReader(b).accept(cn, 0);
289: new AddTimerTransformer(null).transform(cn);
290: cn.accept(cw);
291: cw.toByteArray();
292: }
293: t = System.currentTimeMillis() - t;
294: times[11] = Math.min(t, times[11]);
295: System.out.println("Time to deserialize and reserialize "
296: + classes.size()
297: + " classes with AddTimerTransformer = " + t
298: + " ms");
299: }
300:
301: for (int i = 0; i < 10; ++i) {
302: long t = System.currentTimeMillis();
303: for (int j = 0; j < classes.size(); ++j) {
304: byte[] b = (byte[]) classes.get(j);
305: ClassWriter cw = new ClassWriter(0);
306: ClassNode cn = new ClassNode();
307: new ClassReader(b).accept(cn, 0);
308: Iterator it = cn.methods.iterator();
309: while (it.hasNext()) {
310: MethodNode mn = (MethodNode) it.next();
311: new RemoveGetFieldPutFieldTransformer(null)
312: .transform(mn);
313: }
314: cn.accept(cw);
315: cw.toByteArray();
316: }
317: t = System.currentTimeMillis() - t;
318: times[12] = Math.min(t, times[12]);
319: System.out
320: .println("Time to deserialize and reserialize "
321: + classes.size()
322: + " classes with RemoveGetFieldPutFieldTransformer = "
323: + t + " ms");
324: }
325:
326: for (int i = 0; i < 10; ++i) {
327: int errors = 0;
328: long t = System.currentTimeMillis();
329: for (int j = 0; j < classes.size() / 10; ++j) {
330: byte[] b = (byte[]) classes.get(j);
331: ClassReader cr = new ClassReader(b);
332: ClassNode cn = new ClassNode();
333: cr.accept(cn, 0);
334: List methods = cn.methods;
335: for (int k = 0; k < methods.size(); ++k) {
336: MethodNode method = (MethodNode) methods.get(k);
337: if (method.instructions.size() > 0) {
338: Analyzer a = new Analyzer(
339: new BasicInterpreter());
340: try {
341: a.analyze(cn.name, method);
342: } catch (Throwable th) {
343: ++errors;
344: }
345: }
346: }
347: }
348: t = System.currentTimeMillis() - t;
349: times[13] = Math.min(t, times[13]);
350: System.out.println("Time to analyze " + classes.size() / 10
351: + " classes with BasicInterpreter = " + t + " ms ("
352: + errors + " errors)");
353: }
354:
355: for (int i = 0; i < 10; ++i) {
356: int errors = 0;
357: long t = System.currentTimeMillis();
358: for (int j = 0; j < classes.size() / 10; ++j) {
359: byte[] b = (byte[]) classes.get(j);
360: ClassReader cr = new ClassReader(b);
361: ClassNode cn = new ClassNode();
362: cr.accept(cn, 0);
363: List methods = cn.methods;
364: for (int k = 0; k < methods.size(); ++k) {
365: MethodNode method = (MethodNode) methods.get(k);
366: if (method.instructions.size() > 0) {
367: Analyzer a = new Analyzer(new SimpleVerifier());
368: try {
369: a.analyze(cn.name, method);
370: } catch (Throwable th) {
371: ++errors;
372: }
373: }
374: }
375: }
376: t = System.currentTimeMillis() - t;
377: times[14] = Math.min(t, times[14]);
378: System.out.println("Time to analyze " + classes.size() / 10
379: + " classes with SimpleVerifier = " + t + " ms ("
380: + errors + " errors)");
381: }
382:
383: for (int i = 0; i < times.length; ++i) {
384: System.out.println(times[i]);
385: }
386: System.out.println();
387:
388: double base = 100.0 / times[1];
389: double read = times[0] * base;
390: double write = (times[1] - times[0]) * base;
391: System.out.println("base = 100 (including " + read + " for R, "
392: + write + " for W)");
393: System.out.println("add time = " + times[3] * base
394: + " (including " + read + " for R, "
395: + (times[3] - times[1]) * base + " for T, " + write
396: + " for W)");
397: System.out.println("remove seq = " + times[5] * base
398: + " (including " + read + " for R, "
399: + (times[5] - times[1]) * base + " for T, " + write
400: + " for W)");
401: System.out.println();
402: System.out.println("base' = " + times[2] * base);
403: System.out.println("add time' = " + times[4] * base);
404: System.out.println("remove seq' = " + times[6] * base);
405: System.out.println();
406: System.out.println("compute maxs = " + times[7] * base
407: + " (including " + read + " for R, "
408: + (times[7] - times[1]) * base + " for C, " + write
409: + " for W)");
410: System.out.println("compute frames = " + times[8] * base
411: + " (including " + read + " for R, "
412: + (times[8] - times[1]) * base + " for C, " + write
413: + " for W)");
414: double tread = times[9] * base;
415: double twrite = (times[10] - times[9]) * base;
416: System.out.println();
417: System.out.println("tree base = " + times[10] * base
418: + " (including " + tread + " for R, " + twrite
419: + " for W)");
420: System.out.println("tree add time = " + times[11] * base
421: + " (including " + tread + " for R, "
422: + (times[11] - times[10]) * base + " for T, " + twrite
423: + " for W)");
424: System.out.println("tree remove seq = " + times[12] * base
425: + " (including " + tread + " for R, "
426: + (times[12] - times[10]) * base + " for T, " + twrite
427: + " for W)");
428: System.out.println("basic interpreter = " + times[13] * 10
429: * base + " (including " + tread + " for R, "
430: + (times[13] * 10 - times[10]) * base + " for C, "
431: + twrite + " for W)");
432: System.out.println("simple verifier = " + times[14] * 10 * base
433: + " (including " + tread + " for R, "
434: + (times[14] * 10 - times[10]) * base + " for C, "
435: + twrite + " for W)");
436: }
437: }
|