1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.bcel;
19
20 import static org.junit.jupiter.api.Assertions.fail;
21
22 import java.io.ByteArrayInputStream;
23 import java.io.File;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.util.Arrays;
27 import java.util.Enumeration;
28 import java.util.jar.JarEntry;
29 import java.util.jar.JarFile;
30
31 import org.apache.bcel.classfile.ClassParser;
32 import org.apache.bcel.classfile.JavaClass;
33 import org.apache.bcel.classfile.Method;
34 import org.apache.bcel.generic.ClassGen;
35 import org.apache.bcel.generic.InstructionList;
36 import org.apache.bcel.generic.MethodGen;
37 import org.apache.commons.lang3.SystemProperties;
38 import org.junit.jupiter.api.Test;
39
40 public final class PerformanceTest {
41
42 private static final boolean REPORT = Boolean.parseBoolean(System.getProperty("PerformanceTest.report", "true"));
43
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 b = Arrays.copyOf(b, len);
55 }
56 return b;
57 }
58 len += n;
59 if (len == b.length) {
60 final byte[] c = new byte[b.length + 1000];
61 System.arraycopy(b, 0, c, 0, len);
62 b = c;
63 }
64 }
65 }
66
67 private static void test(final File lib) throws IOException {
68 final NanoTimer total = new NanoTimer();
69 final NanoTimer parseTime = new NanoTimer();
70 final NanoTimer cgenTime = new NanoTimer();
71 final NanoTimer mgenTime = new NanoTimer();
72 final NanoTimer mserTime = new NanoTimer();
73 final NanoTimer serTime = new NanoTimer();
74
75 System.out.println("Parsing " + lib);
76
77 total.start();
78 try (JarFile jar = new JarFile(lib)) {
79 final Enumeration<?> en = jar.entries();
80
81 while (en.hasMoreElements()) {
82 final JarEntry e = (JarEntry) en.nextElement();
83 if (e.getName().endsWith(JavaClass.EXTENSION)) {
84 byte[] bytes;
85 try (InputStream in = jar.getInputStream(e)) {
86 bytes = read(in);
87 }
88
89 parseTime.start();
90 final JavaClass clazz = new ClassParser(new ByteArrayInputStream(bytes), e.getName()).parse();
91 parseTime.stop();
92
93 cgenTime.start();
94 final ClassGen cg = new ClassGen(clazz);
95 cgenTime.stop();
96
97 final Method[] methods = cg.getMethods();
98 for (final Method m : methods) {
99 mgenTime.start();
100 final MethodGen mg = new MethodGen(m, cg.getClassName(), cg.getConstantPool());
101 final InstructionList il = mg.getInstructionList();
102 mgenTime.stop();
103
104 mserTime.start();
105 if (il != null) {
106 mg.getInstructionList().setPositions();
107 mg.setMaxLocals();
108 mg.setMaxStack();
109 }
110 cg.replaceMethod(m, mg.getMethod());
111 mserTime.stop();
112 }
113
114 serTime.start();
115 cg.getJavaClass().getBytes();
116 serTime.stop();
117 }
118 }
119 }
120 total.stop();
121 if (REPORT) {
122 System.out.println("ClassParser.parse: " + parseTime);
123 System.out.println("ClassGen.init: " + cgenTime);
124 System.out.println("MethodGen.init: " + mgenTime);
125 System.out.println("MethodGen.getMethod: " + mserTime);
126 System.out.println("ClassGen.getJavaClass.getBytes: " + serTime);
127 System.out.println("Total: " + total);
128 System.out.println();
129 }
130 }
131
132 @Test
133 public void testPerformance() {
134 final File javaLib = new File(SystemProperties.getJavaHome(), "lib");
135 javaLib.listFiles(file -> {
136 if (file.getName().endsWith(".jar")) {
137 try {
138 test(file);
139 } catch (final IOException e) {
140 fail(e.getMessage());
141 }
142 }
143 return false;
144 });
145 }
146
147 }