1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.bcel;
21
22 import static org.junit.jupiter.api.Assertions.fail;
23
24 import java.io.ByteArrayInputStream;
25 import java.io.File;
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.util.Arrays;
29 import java.util.Enumeration;
30 import java.util.jar.JarEntry;
31 import java.util.jar.JarFile;
32
33 import org.apache.bcel.classfile.ClassParser;
34 import org.apache.bcel.classfile.JavaClass;
35 import org.apache.bcel.classfile.Method;
36 import org.apache.bcel.generic.ClassGen;
37 import org.apache.bcel.generic.InstructionList;
38 import org.apache.bcel.generic.MethodGen;
39 import org.apache.commons.lang3.SystemProperties;
40 import org.junit.jupiter.api.Test;
41
42 public final class PerformanceTest {
43
44 private static final boolean REPORT = Boolean.parseBoolean(System.getProperty("PerformanceTest.report", "true"));
45
46 private static byte[] read(final InputStream is) throws IOException {
47 if (is == null) {
48 throw new IOException("Class not found");
49 }
50 byte[] b = new byte[is.available()];
51 int len = 0;
52 while (true) {
53 final int n = is.read(b, len, b.length - len);
54 if (n == -1) {
55 if (len < b.length) {
56 b = Arrays.copyOf(b, len);
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
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(JavaClass.EXTENSION)) {
86 final 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
134 @Test
135 void testPerformance() {
136 final File javaLib = new File(SystemProperties.getJavaHome(), "lib");
137 javaLib.listFiles(file -> {
138 if (file.getName().endsWith(".jar")) {
139 try {
140 test(file);
141 } catch (final IOException e) {
142 fail(e.getMessage());
143 }
144 }
145 return false;
146 });
147 }
148
149 }