/*
* 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.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import junit.framework.TestCase;
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;
public final class PerformanceTest extends TestCase {
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) {
int n = is.read(b, len, b.length - len);
if (n == -1) {
if (len < b.length) {
byte[] c = new byte[len];
System.arraycopy(b, 0, c, 0, len);
b = c;
}
return b;
}
len += n;
if (len == b.length) {
byte[] c = new byte[b.length + 1000];
System.arraycopy(b, 0, c, 0, len);
b = c;
}
}
}
private static void test(int fraction) throws IOException {
NanoTimer total = new NanoTimer();
NanoTimer parseTime = new NanoTimer();
NanoTimer cgenTime = new NanoTimer();
NanoTimer mgenTime = new NanoTimer();
NanoTimer mserTime = new NanoTimer();
NanoTimer serTime = new NanoTimer();
total.start();
String javaHome = System.getProperty("java.home");
JarFile jar = new JarFile(javaHome + "/lib/dt.jar");
Enumeration<?> en = jar.entries();
int i = 0;
while (en.hasMoreElements()) {
JarEntry e = (JarEntry) en.nextElement();
if (e.getName().endsWith(".class") && i++ % fraction == 0) {
InputStream in = jar.getInputStream(e);
byte[] bytes = read(in);
parseTime.start();
JavaClass clazz = new ClassParser(new ByteArrayInputStream(bytes), e.getName())
.parse();
parseTime.stop();
cgenTime.start();
ClassGen cg = new ClassGen(clazz);
cgenTime.stop();
Method[] methods = cg.getMethods();
for (Method m : methods) {
mgenTime.start();
MethodGen mg = new MethodGen(m, cg.getClassName(), cg.getConstantPool());
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();
}
}
jar.close();
total.stop();
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() throws IOException {
test(1);
test(1);
test(1);
}
}