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.junit.jupiter.api.Test;
38
39 public final class PerformanceTest {
40
41 private static final boolean REPORT = Boolean.parseBoolean(System.getProperty("PerformanceTest.report", "true"));
42
43 private static byte[] read(final InputStream is) throws IOException {
44 if (is == null) {
45 throw new IOException("Class not found");
46 }
47 byte[] b = new byte[is.available()];
48 int len = 0;
49 while (true) {
50 final int n = is.read(b, len, b.length - len);
51 if (n == -1) {
52 if (len < b.length) {
53 b = Arrays.copyOf(b, len);
54 }
55 return b;
56 }
57 len += n;
58 if (len == b.length) {
59 final byte[] c = new byte[b.length + 1000];
60 System.arraycopy(b, 0, c, 0, len);
61 b = c;
62 }
63 }
64 }
65
66 private static void test(final File lib) throws IOException {
67 final NanoTimer total = new NanoTimer();
68 final NanoTimer parseTime = new NanoTimer();
69 final NanoTimer cgenTime = new NanoTimer();
70 final NanoTimer mgenTime = new NanoTimer();
71 final NanoTimer mserTime = new NanoTimer();
72 final NanoTimer serTime = new NanoTimer();
73
74 System.out.println("Parsing " + lib);
75
76 total.start();
77 try (JarFile jar = new JarFile(lib)) {
78 final Enumeration<?> en = jar.entries();
79
80 while (en.hasMoreElements()) {
81 final JarEntry e = (JarEntry) en.nextElement();
82 if (e.getName().endsWith(JavaClass.EXTENSION)) {
83 byte[] bytes;
84 try (InputStream in = jar.getInputStream(e)) {
85 bytes = read(in);
86 }
87
88 parseTime.start();
89 final JavaClass clazz = new ClassParser(new ByteArrayInputStream(bytes), e.getName()).parse();
90 parseTime.stop();
91
92 cgenTime.start();
93 final ClassGen cg = new ClassGen(clazz);
94 cgenTime.stop();
95
96 final Method[] methods = cg.getMethods();
97 for (final Method m : methods) {
98 mgenTime.start();
99 final MethodGen mg = new MethodGen(m, cg.getClassName(), cg.getConstantPool());
100 final InstructionList il = mg.getInstructionList();
101 mgenTime.stop();
102
103 mserTime.start();
104 if (il != null) {
105 mg.getInstructionList().setPositions();
106 mg.setMaxLocals();
107 mg.setMaxStack();
108 }
109 cg.replaceMethod(m, mg.getMethod());
110 mserTime.stop();
111 }
112
113 serTime.start();
114 cg.getJavaClass().getBytes();
115 serTime.stop();
116 }
117 }
118 }
119 total.stop();
120 if (REPORT) {
121 System.out.println("ClassParser.parse: " + parseTime);
122 System.out.println("ClassGen.init: " + cgenTime);
123 System.out.println("MethodGen.init: " + mgenTime);
124 System.out.println("MethodGen.getMethod: " + mserTime);
125 System.out.println("ClassGen.getJavaClass.getBytes: " + serTime);
126 System.out.println("Total: " + total);
127 System.out.println();
128 }
129 }
130
131 @Test
132 public void testPerformance() {
133 final File javaLib = new File(System.getProperty("java.home"), "lib");
134 javaLib.listFiles(file -> {
135 if (file.getName().endsWith(".jar")) {
136 try {
137 test(file);
138 } catch (final IOException e) {
139 fail(e.getMessage());
140 }
141 }
142 return false;
143 });
144 }
145
146 }