blob: a5fabac6e7e0baf6d41dd6adf80d2050524bf216 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.bcel;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import org.apache.bcel.classfile.ClassParser;
import org.apache.bcel.classfile.JavaClass;
import org.apache.bcel.classfile.Method;
import org.apache.bcel.generic.ClassGen;
import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.MethodGen;
import org.junit.Assert;
import junit.framework.TestCase;
public final class PerformanceTest extends TestCase {
private static final boolean REPORT = Boolean.parseBoolean(System.getProperty("PerformanceTest.report", "true"));;
private static byte[] read(final InputStream is) throws IOException {
if (is == null) {
throw new IOException("Class not found");
}
byte[] b = new byte[is.available()];
int len = 0;
while (true) {
final int n = is.read(b, len, b.length - len);
if (n == -1) {
if (len < b.length) {
final byte[] c = new byte[len];
System.arraycopy(b, 0, c, 0, len);
b = c;
}
return b;
}
len += n;
if (len == b.length) {
final byte[] c = new byte[b.length + 1000];
System.arraycopy(b, 0, c, 0, len);
b = c;
}
}
}
private static void test(final File lib) throws IOException {
final NanoTimer total = new NanoTimer();
final NanoTimer parseTime = new NanoTimer();
final NanoTimer cgenTime = new NanoTimer();
final NanoTimer mgenTime = new NanoTimer();
final NanoTimer mserTime = new NanoTimer();
final NanoTimer serTime = new NanoTimer();
System.out.println("parsing " + lib);
total.start();
try (JarFile jar = new JarFile(lib)) {
final Enumeration<?> en = jar.entries();
while (en.hasMoreElements()) {
final JarEntry e = (JarEntry) en.nextElement();
if (e.getName().endsWith(".class")) {
byte[] bytes;
try (InputStream in = jar.getInputStream(e)) {
bytes = read(in);
}
parseTime.start();
final JavaClass clazz = new ClassParser(new ByteArrayInputStream(bytes), e.getName()).parse();
parseTime.stop();
cgenTime.start();
final ClassGen cg = new ClassGen(clazz);
cgenTime.stop();
final Method[] methods = cg.getMethods();
for (final Method m : methods) {
mgenTime.start();
final MethodGen mg = new MethodGen(m, cg.getClassName(), cg.getConstantPool());
final InstructionList il = mg.getInstructionList();
mgenTime.stop();
mserTime.start();
if (il != null) {
mg.getInstructionList().setPositions();
mg.setMaxLocals();
mg.setMaxStack();
}
cg.replaceMethod(m, mg.getMethod());
mserTime.stop();
}
serTime.start();
cg.getJavaClass().getBytes();
serTime.stop();
}
}
}
total.stop();
if (REPORT) {
System.out.println("ClassParser.parse: " + parseTime);
System.out.println("ClassGen.init: " + cgenTime);
System.out.println("MethodGen.init: " + mgenTime);
System.out.println("MethodGen.getMethod: " + mserTime);
System.out.println("ClassGen.getJavaClass.getBytes: " + serTime);
System.out.println("Total: " + total);
System.out.println();
}
}
public void testPerformance() {
final File javaLib = new File(System.getProperty("java.home"), "lib");
javaLib.listFiles(new FileFilter() {
@Override
public boolean accept(final File file) {
if(file.getName().endsWith(".jar")) {
try {
test(file);
} catch (final IOException e) {
Assert.fail(e.getMessage());
}
}
return false;
}
});
}
}