Commit fd883951 authored by Eric Bruneton's avatar Eric Bruneton

Improve the class generation benchmark by using the JMH framework.

Results:
Benchmark                             Mode  Cnt       Score      Error  Units
GeneratorBenchmark.asm4_0            thrpt   20  753119,277 ± 1890,328  ops/s
GeneratorBenchmark.asm5_0            thrpt   20  729869,073 ± 2328,108  ops/s
GeneratorBenchmark.asm6_0            thrpt   20  728330,694 ± 2244,506  ops/s
GeneratorBenchmark.asm6_1            thrpt   20  847886,985 ± 2767,943  ops/s
GeneratorBenchmark.aspectJBcel       thrpt   20  274363,976 ± 1171,862  ops/s
GeneratorBenchmark.bcel              thrpt   20  196715,573 ±  797,970  ops/s
GeneratorBenchmark.cojen             thrpt   20  191329,604 ±  898,662  ops/s
GeneratorBenchmark.csgBytecode       thrpt   20  325157,840 ± 1065,897  ops/s
GeneratorBenchmark.gnuByteCode       thrpt   20  245634,219 ± 1061,192  ops/s
GeneratorBenchmark.jclassLib         thrpt   20  280383,253 ±  973,727  ops/s
GeneratorBenchmark.jiapi             thrpt   20   75012,298 ±  325,473  ops/s
GeneratorBenchmark.mozillaClassFile  thrpt   20  303011,386 ± 1629,259  ops/s
parent b5e6dc44
Pipeline #535 passed with stage
in 10 minutes and 49 seconds
// ASM: a very small and fast Java bytecode manipulation framework
// Copyright (c) 2000-2011 INRIA, France Telecom
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
package org.objectweb.asm.benchmarks;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
/**
* A "Hello World!" class generator using the ASM library.
*
* @author Eric Bruneton
*/
public class ASMGenerator implements Generator {
public String getVersion() {
for (int i = 6; i >= 4; --i) {
try {
String version = "ASM" + i;
if (Opcodes.class.getField(version) != null) {
return version;
}
} catch (NoSuchFieldException e) {
}
}
return "";
Please register or sign in to reply
}
public byte[] generateClass() {
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
classWriter.visit(
Opcodes.V1_1, Opcodes.ACC_PUBLIC, "HelloWorld", null, "java/lang/Object", null);
classWriter.visitSource("HelloWorld.java", null);
MethodVisitor methodVisitor =
classWriter.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
methodVisitor.visitVarInsn(Opcodes.ALOAD, 0);
methodVisitor.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
methodVisitor.visitInsn(Opcodes.RETURN);
methodVisitor.visitMaxs(0, 0);
methodVisitor.visitEnd();
methodVisitor =
classWriter.visitMethod(
Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
methodVisitor.visitFieldInsn(
Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
methodVisitor.visitLdcInsn("Hello world!");
methodVisitor.visitMethodInsn(
Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
methodVisitor.visitInsn(Opcodes.RETURN);
methodVisitor.visitMaxs(0, 0);
methodVisitor.visitEnd();
return classWriter.toByteArray();
}
}
// ASM: a very small and fast Java bytecode manipulation framework
// Copyright (c) 2000-2011 INRIA, France Telecom
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
package org.objectweb.asm.benchmarks;
import org.aspectj.apache.bcel.Constants;
import org.aspectj.apache.bcel.classfile.ConstantPool;
import org.aspectj.apache.bcel.generic.ArrayType;
import org.aspectj.apache.bcel.generic.ClassGen;
import org.aspectj.apache.bcel.generic.InstructionFactory;
import org.aspectj.apache.bcel.generic.InstructionList;
import org.aspectj.apache.bcel.generic.MethodGen;
import org.aspectj.apache.bcel.generic.Type;
/**
* A "Hello World!" class generator using the AspectJ BCEL library.
*
* @author Eric Bruneton
*/
public class AspectJBCELGenerator implements Generator {
private static final Type PRINT_STREAM_TYPE = Type.getType("Ljava/io/PrintStream;");
@Override
public String getVersion() {
return null;
}
@Override
public byte[] generateClass() {
ClassGen classGen =
new ClassGen(
"HelloWorld", "java/lang/Object", "HelloWorld.java", Constants.ACC_PUBLIC, null);
classGen.addEmptyConstructor(Constants.ACC_PUBLIC);
ConstantPool constantPoolGen = classGen.getConstantPool();
InstructionList insnList = new InstructionList();
InstructionFactory insnFactory = new InstructionFactory(classGen);
MethodGen methodGen =
new MethodGen(
Constants.ACC_STATIC | Constants.ACC_PUBLIC,
Type.VOID,
new Type[] {new ArrayType(Type.STRING, 1)},
null,
"main",
"HelloWorld",
insnList,
constantPoolGen);
insnList.append(insnFactory.createGetStatic("java/lang/System", "out", PRINT_STREAM_TYPE));
insnList.append(insnFactory.createConstant("Hello world!"));
insnList.append(
insnFactory.createInvoke(
"java.io.PrintStream",
"println",
Type.VOID,
new Type[] {Type.STRING},
Constants.INVOKESPECIAL));
methodGen.setMaxStack();
classGen.addMethod(methodGen.getMethod());
return classGen.getJavaClass().getBytes();
}
}
// ASM: a very small and fast Java bytecode manipulation framework
// Copyright (c) 2000-2011 INRIA, France Telecom
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
package org.objectweb.asm.benchmarks;
import org.apache.bcel.Constants;
import org.apache.bcel.generic.ArrayType;
import org.apache.bcel.generic.ClassGen;
import org.apache.bcel.generic.ConstantPoolGen;
import org.apache.bcel.generic.InstructionFactory;
import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.MethodGen;
import org.apache.bcel.generic.PUSH;
import org.apache.bcel.generic.Type;
/**
* A "Hello World!" class generator using the BCEL library.
*
* @author Eric Bruneton
*/
public class BCELGenerator implements Generator {
private static final Type PRINT_STREAM_TYPE = Type.getType("Ljava/io/PrintStream;");
@Override
public String getVersion() {
return null;
}
@Override
public byte[] generateClass() {
ClassGen classGen =
new ClassGen(
"HelloWorld", "java/lang/Object", "HelloWorld.java", Constants.ACC_PUBLIC, null);
classGen.addEmptyConstructor(Constants.ACC_PUBLIC);
ConstantPoolGen constantPoolGen = classGen.getConstantPool();
InstructionList insnList = new InstructionList();
InstructionFactory insnFactory = new InstructionFactory(classGen);
MethodGen methodGen =
new MethodGen(
Constants.ACC_STATIC | Constants.ACC_PUBLIC,
Type.VOID,
new Type[] {new ArrayType(Type.STRING, 1)},
null,
"main",
"HelloWorld",
insnList,
constantPoolGen);
insnList.append(insnFactory.createGetStatic("java/lang/System", "out", PRINT_STREAM_TYPE));
insnList.append(new PUSH(constantPoolGen, "Hello world!"));
insnList.append(
insnFactory.createInvoke(
"java.io.PrintStream",
"println",
Type.VOID,
new Type[] {Type.STRING},
Constants.INVOKESPECIAL));
methodGen.setMaxStack();
classGen.addMethod(methodGen.getMethod());
return classGen.getJavaClass().getBytes();
}
}
// ASM: a very small and fast Java bytecode manipulation framework
// Copyright (c) 2000-2011 INRIA, France Telecom
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
package org.objectweb.asm.benchmarks;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import org.cojen.classfile.ClassFile;
import org.cojen.classfile.CodeBuilder;
import org.cojen.classfile.MethodInfo;
import org.cojen.classfile.Modifiers;
import org.cojen.classfile.TypeDesc;
/**
* A "Hello World!" class generator using the Cojen library.
*
* @author Eric Bruneton
*/
public class CojenGenerator implements Generator {
static TypeDesc printStream = TypeDesc.forClass("java.io.PrintStream");
Please register or sign in to reply
@Override
public String getVersion() {
return null;
}
@Override
public byte[] generateClass() {
ClassFile classFile = new ClassFile("HelloWorld");
classFile.setSourceFile("HelloWorld.java");
classFile.addDefaultConstructor();
TypeDesc[] params = new TypeDesc[] {TypeDesc.STRING.toArrayType()};
MethodInfo methodInfo = classFile.addMethod(Modifiers.PUBLIC_STATIC, "main", null, params);
CodeBuilder codeBuilder = new CodeBuilder(methodInfo);
codeBuilder.loadStaticField("java.lang.System", "out", printStream);
codeBuilder.loadConstant("Hello world!");
codeBuilder.invokeVirtual(printStream, "println", null, new TypeDesc[] {TypeDesc.STRING});
codeBuilder.returnVoid();
try {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
classFile.writeTo(byteArrayOutputStream);
return byteArrayOutputStream.toByteArray();
} catch (IOException e) {
throw new RuntimeException("Class generation failed", e);
}
}
}
// ASM: a very small and fast Java bytecode manipulation framework
// Copyright (c) 2000-2011 INRIA, France Telecom
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
package org.objectweb.asm.benchmarks;
import com.claritysys.jvm.builder.CodeBuilder;
import com.claritysys.jvm.classfile.CfMethod;
import com.claritysys.jvm.classfile.ClassFile;
import com.claritysys.jvm.classfile.ConstantPool;
import com.claritysys.jvm.classfile.JVM;
/**
* A "Hello World!" class generator using the CSG Bytecode library.
*
* @author Eric Bruneton
*/
public class CsgBytecodeGenerator implements Generator {
@Override
public String getVersion() {
Please register or sign in to reply
return null;
}
@Override
public byte[] generateClass() {
ClassFile classFile = new ClassFile("HelloWorld", "java/lang/Object", "HelloWorld.java");
ConstantPool constantPool = classFile.getConstantPool();
CfMethod method = classFile.addMethod(JVM.ACC_PUBLIC, "<init>", "()V");
CodeBuilder code = new CodeBuilder(method);
code.add(JVM.ALOAD_0);
code.add(
JVM.INVOKESPECIAL, constantPool.addMethodRef(false, "java/lang/Object", "<init>", "()V"));
code.add(JVM.RETURN);
code.flush();
method = classFile.addMethod(JVM.ACC_PUBLIC + JVM.ACC_STATIC, "main", "([Ljava/lang/String;)V");
code = new CodeBuilder(method);
code.add(
JVM.GETSTATIC,
constantPool.addFieldRef("java/lang/System", "out", "Ljava/io/PrintStream;"));
code.add(JVM.LDC, "Hello world!");
code.add(
JVM.INVOKEVIRTUAL,
constantPool.addMethodRef(
false, "java/io/PrintStream", "println", "(Ljava/lang/String;)V"));
code.add(JVM.RETURN);
code.flush();
return classFile.writeToArray();
}
}
// ASM: a very small and fast Java bytecode manipulation framework
// Copyright (c) 2000-2011 INRIA, France Telecom
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
package org.objectweb.asm.benchmarks;
/**
* A "Hello World!" class generator.
*
* @author Eric Bruneton
*/
public interface Generator {
/** @return the version of this generator. */
Please register or sign in to reply
String getVersion();
/**
* Generates a "Hello World!" class.
*
* @return the JVMS ClassFile structure of the generated class.
*/
byte[] generateClass();
}
// ASM: a very small and fast Java bytecode manipulation framework
// Copyright (c) 2000-2011 INRIA, France Telecom
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
package org.objectweb.asm.benchmarks;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
/**
* A benchmark to measure the performance of several libraries when generating a "Hello World!"
* class.
*
* @author Eric Bruneton
*/
@State(Scope.Thread)
public class GeneratorBenchmark {
// The directories where the different versions of ASM can be found.
private static final String BUILD_DIR = "/benchmarks/write/build/";
private static final String ASM4_0 = BUILD_DIR + "asm4/";
private static final String ASM5_0 = BUILD_DIR + "asm5/";
private static final String ASM6_0 = BUILD_DIR + "asm6/";
private static final String ASM6_1 = "/asm/build/classes/java/main/";
// The fully qualified name of the ASMGenerator class.
private static final String ASM_GENERATOR = "org.objectweb.asm.benchmarks.ASMGenerator";
Generator asm4_0;
Generator asm5_0;
Generator asm6_0;
Generator asm6_1;
Generator aspectJBcel;
Generator bcel;
Generator cojen;
Generator csgBytecode;
Generator gnuByteCode;
Generator jclassLib;
Generator jiapi;
Generator mozillaClassFile;
/**
* Prepares the benchmark by creating a {@link Generator} for each library to be tested.
*
* @throws Exception if an error occurs.
*/
@Setup
public void prepare() throws Exception {
String userDir = System.getProperty("user.dir");
asm4_0 = new ASMGeneratorFactory(userDir + ASM4_0).newAsmGenerator();
asm5_0 = new ASMGeneratorFactory(userDir + ASM5_0).newAsmGenerator();
asm6_0 = new ASMGeneratorFactory(userDir + ASM6_0).newAsmGenerator();
asm6_1 = new ASMGeneratorFactory(userDir + ASM6_1).newAsmGenerator();
aspectJBcel = new AspectJBCELGenerator();
bcel = new BCELGenerator();
cojen = new CojenGenerator();
csgBytecode = new CsgBytecodeGenerator();
gnuByteCode = new GnuByteCodeGenerator();
jclassLib = new JClassLibGenerator();
jiapi = new JiapiGenerator();
mozillaClassFile = new MozillaClassFileGenerator();
// Check that the correct versions of ASM have been loaded.
if (!asm4_0.getVersion().equals("ASM4")
Please register or sign in to reply
|| !asm5_0.getVersion().equals("ASM5")
|| !asm6_0.getVersion().equals("ASM6")
|| !asm6_1.getVersion().equals("ASM6")) {
throw new IllegalStateException();
}
}
@Benchmark
public byte[] asm4_0() {
return asm4_0.generateClass();
}
@Benchmark
public byte[] asm5_0() {
return asm5_0.generateClass();
}
@Benchmark
public byte[] asm6_0() {
return asm6_0.generateClass();
}
@Benchmark
public byte[] asm6_1() {
return asm6_1.generateClass();
}
@Benchmark
public byte[] aspectJBcel() {
return aspectJBcel.generateClass();
}
@Benchmark
public byte[] bcel() {
return bcel.generateClass();
}
@Benchmark
public byte[] cojen() {
return cojen.generateClass();
}
@Benchmark
public byte[] csgBytecode() {
return csgBytecode.generateClass();
}
@Benchmark
public byte[] gnuByteCode() {
return gnuByteCode.generateClass();
}
@Benchmark
public byte[] jclassLib() {
return jclassLib.generateClass();
}
@Benchmark
public byte[] jiapi() {
return jiapi.generateClass();
}
@Benchmark
public byte[] mozillaClassFile() {
return mozillaClassFile.generateClass();
}
/** A factory of {@link ASMGenerator} objects, using a specific version of the ASM library. */
private static class ASMGeneratorFactory extends URLClassLoader {
/**
* Constructs a {@link ASMGeneratorFactory}.
*
* @param asmDirectory the directory where the ASM library classes can be found.
* @throws MalformedURLException
*/
ASMGeneratorFactory(final String asmDirectory) throws MalformedURLException {
super(new URL[] {new URL("file://" + asmDirectory)});
}
/**
* @return a new {@link ASMGenerator} instance.
* @throws Exception
*/
public Generator newAsmGenerator() throws Exception {
return (Generator) loadClass(ASM_GENERATOR).newInstance();
}
protected Class<?> loadClass(final String name, final boolean resolve)
throws ClassNotFoundException {
// Force the loading of the ASMGenerator class by this class loader (and not its parent). This
// is needed to make sure that the classes it references (i.e. the ASM library classes) will
// be loaded by this class loader too.
if (name.equals(ASM_GENERATOR)) {
InputStream inputStream = getResourceAsStream(name.replace('.', '/') + ".class");
Please register or sign in to reply
try {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();