1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *   http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 package org.apache.bcel;
20 
21 import java.io.ByteArrayInputStream;
22 import java.io.File;
23 import java.io.FileFilter;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.util.Enumeration;
27 import java.util.jar.JarEntry;
28 import java.util.jar.JarFile;
29 
30 import org.apache.bcel.classfile.ClassParser;
31 import org.apache.bcel.classfile.JavaClass;
32 import org.apache.bcel.classfile.Method;
33 import org.apache.bcel.generic.ClassGen;
34 import org.apache.bcel.generic.InstructionList;
35 import org.apache.bcel.generic.MethodGen;
36 import org.junit.Assert;
37 
38 import junit.framework.TestCase;
39 
40 public final class PerformanceTest extends TestCase {
41 
42     private static final boolean REPORT = Boolean.parseBoolean(System.getProperty("PerformanceTest.report", "true"));;
43 
read(final InputStream is)44     private static byte[] read(final InputStream is) throws IOException {
45         if (is == null) {
46             throw new IOException("Class not found");
47         }
48         byte[] b = new byte[is.available()];
49         int len = 0;
50         while (true) {
51             final int n = is.read(b, len, b.length - len);
52             if (n == -1) {
53                 if (len < b.length) {
54                     final byte[] c = new byte[len];
55                     System.arraycopy(b, 0, c, 0, len);
56                     b = c;
57                 }
58                 return b;
59             }
60             len += n;
61             if (len == b.length) {
62                 final byte[] c = new byte[b.length + 1000];
63                 System.arraycopy(b, 0, c, 0, len);
64                 b = c;
65             }
66         }
67     }
68 
test(final File lib)69     private static void test(final File lib) throws IOException {
70         final NanoTimer total = new NanoTimer();
71         final NanoTimer parseTime = new NanoTimer();
72         final NanoTimer cgenTime = new NanoTimer();
73         final NanoTimer mgenTime = new NanoTimer();
74         final NanoTimer mserTime = new NanoTimer();
75         final NanoTimer serTime = new NanoTimer();
76 
77         System.out.println("parsing " + lib);
78 
79         total.start();
80         try (JarFile jar = new JarFile(lib)) {
81             final Enumeration<?> en = jar.entries();
82 
83             while (en.hasMoreElements()) {
84                 final JarEntry e = (JarEntry) en.nextElement();
85                 if (e.getName().endsWith(".class")) {
86                     byte[] bytes;
87                     try (InputStream in = jar.getInputStream(e)) {
88                         bytes = read(in);
89                     }
90 
91                     parseTime.start();
92                     final JavaClass clazz = new ClassParser(new ByteArrayInputStream(bytes), e.getName()).parse();
93                     parseTime.stop();
94 
95                     cgenTime.start();
96                     final ClassGen cg = new ClassGen(clazz);
97                     cgenTime.stop();
98 
99                     final Method[] methods = cg.getMethods();
100                     for (final Method m : methods) {
101                         mgenTime.start();
102                         final MethodGen mg = new MethodGen(m, cg.getClassName(), cg.getConstantPool());
103                         final InstructionList il = mg.getInstructionList();
104                         mgenTime.stop();
105 
106                         mserTime.start();
107                         if (il != null) {
108                             mg.getInstructionList().setPositions();
109                             mg.setMaxLocals();
110                             mg.setMaxStack();
111                         }
112                         cg.replaceMethod(m, mg.getMethod());
113                         mserTime.stop();
114                     }
115 
116                     serTime.start();
117                     cg.getJavaClass().getBytes();
118                     serTime.stop();
119                 }
120             }
121         }
122         total.stop();
123         if (REPORT) {
124             System.out.println("ClassParser.parse: " + parseTime);
125             System.out.println("ClassGen.init: " + cgenTime);
126             System.out.println("MethodGen.init: " + mgenTime);
127             System.out.println("MethodGen.getMethod: " + mserTime);
128             System.out.println("ClassGen.getJavaClass.getBytes: " + serTime);
129             System.out.println("Total: " + total);
130             System.out.println();
131         }
132     }
133 
testPerformance()134     public void testPerformance() {
135         final File javaLib = new File(System.getProperty("java.home"), "lib");
136         javaLib.listFiles(new FileFilter() {
137 
138             @Override
139             public boolean accept(final File file) {
140                 if(file.getName().endsWith(".jar")) {
141                     try {
142                         test(file);
143                     } catch (final IOException e) {
144                         Assert.fail(e.getMessage());
145                     }
146                 }
147                 return false;
148             }
149         });
150     }
151 
152 }
153