blob: 0c46e44ec3e9688b38de9902ea0c18cc1ddab449 [file] [log] [blame]
/***
* ASM performance test: measures the performances of asm package
* Copyright (c) 2002,2003 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.test.perf;
import java.io.File;
import java.io.InputStream;
import java.io.FileOutputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
/**
* @author Eric Bruneton
*/
public abstract class ALL extends ClassLoader {
private static ZipFile zip;
private static ZipOutputStream dst;
private static int mode;
private static int total;
private static int totalSize;
private static double[][] perfs;
static boolean compute;
static boolean skipDebug;
public static void main (String[] args) throws Exception {
System.out.println("Comparing ASM, BCEL, SERP and Javassist performances...");
System.out.println("This may take 20 to 30 minutes\n");
// measures performances
System.out.println("ASM PERFORMANCES\n");
new ASM().perfs(args);
double[][] asmPerfs = perfs;
System.out.println("\nBCEL PERFORMANCES\n");
new BCEL().perfs(args);
double[][] bcelPerfs = perfs;
System.out.println("\nSERP PERFORMANCES\n");
new SERP().perfs(args);
double[][] serpPerfs = perfs;
System.out.println("\nJavassist PERFORMANCES\n");
new Javassist().perfs(args);
double[][] javassistPerfs = perfs;
// prints results
System.out.println("\nGLOBAL RESULTS");
System.out.println("\nWITH DEBUG INFORMATION\n");
for (int step = 0; step < 2; ++step) {
for (mode = 0; mode < 4; ++mode) {
switch (mode) {
case 0: System.out.print("NO ADAPT: "); break;
case 1: System.out.print("NULL ADAPT: "); break;
case 2: System.out.print("COMPUTE MAXS: "); break;
default: System.out.print("ADD COUNTER: "); break;
}
System.out.print((float)asmPerfs[step][mode] + " ms");
if (mode > 0) {
System.out.print(" (*");
System.out.print((float)(asmPerfs[step][mode]/asmPerfs[step][0]));
System.out.print(")");
}
System.out.print(" ");
System.out.print((float)bcelPerfs[step][mode] + " ms");
if (mode > 0) {
System.out.print(" (*");
System.out.print((float)(bcelPerfs[step][mode]/bcelPerfs[step][0]));
System.out.print(")");
}
System.out.print(" ");
System.out.print((float)serpPerfs[step][mode] + " ms");
if (mode > 0) {
System.out.print(" (*");
System.out.print((float)(serpPerfs[step][mode]/serpPerfs[step][0]));
System.out.print(")");
}
System.out.print(" ");
System.out.print((float)javassistPerfs[step][mode] + " ms");
if (mode > 0) {
System.out.print(" (*");
System.out.print((float)(javassistPerfs[step][mode]/javassistPerfs[step][0]));
System.out.print(")");
}
System.out.println();
}
if (step == 0) {
System.out.println("\nWITHOUT DEBUG INFORMATION\n");
}
}
System.out.println("\nRELATIVE RESULTS");
System.out.println("\nWITH DEBUG INFORMATION\n");
for (int step = 0; step < 2; ++step) {
System.err.println("[MEASURE ASM BCEL SERP Javassist]");
for (mode = 1; mode < 4; ++mode) {
int base;
switch (mode) {
case 1: System.out.print("NULL ADAPT: "); base = 0; break;
case 2: System.out.print("COMPUTE MAXS: "); base = 1; break;
default: System.out.print("ADD COUNTER: "); base = 1; break;
}
double ref = asmPerfs[step][mode] - asmPerfs[step][base];
System.out.print((float)ref + " ms ");
double f = bcelPerfs[step][mode] - bcelPerfs[step][base];
System.out.print((float)f + " ms (*");
System.out.print((float)(f/ref));
System.out.print(") ");
double g = serpPerfs[step][mode] - serpPerfs[step][base];
System.out.print((float)g + " ms (*");
System.out.print((float)(g/ref));
System.out.print(")");
double h = javassistPerfs[step][mode] - javassistPerfs[step][base];
System.out.print((float)h + " ms (*");
System.out.print((float)(h/ref));
System.out.print(")");
System.out.println();
}
if (step == 0) {
System.out.println("\nWITHOUT DEBUG INFORMATION\n");
}
}
}
void perfs (final String[] args) throws Exception {
// prepares zip files, if necessary
if (!(new File(args[0] + "classes1.zip").exists())) {
System.out.println("Preparing zip files from " + args[1] + "...");
for (int step = 0; step < 2; ++step) {
dst = new ZipOutputStream(
new FileOutputStream(args[0] + "classes" + (step + 1) + ".zip"));
mode = step == 0 ? 1 : 4;
for (int i = 1; i < args.length; ++i) {
ALL loader = newInstance();
zip = new ZipFile(args[i]);
Enumeration entries = zip.entries();
while (entries.hasMoreElements()) {
String s = ((ZipEntry)entries.nextElement()).getName();
if (s.endsWith(".class")) {
s = s.substring(0, s.length() - 6).replace('/', '.');
loader.loadClass(s);
}
}
}
dst.close();
dst = null;
}
System.out.println();
}
// measures performances
perfs = new double[2][4];
System.out.println("FIRST STEP: WITH DEBUG INFORMATION");
for (int step = 0; step < 2; ++step) {
zip = new ZipFile(args[0] + "classes" + (step + 1) + ".zip");
for (mode = 0; mode < 4; ++mode) {
for (int i = 0; i < 4; ++i) {
ALL loader = newInstance();
total = 0;
totalSize = 0;
Enumeration entries = zip.entries();
double t = System.currentTimeMillis();
while (entries.hasMoreElements()) {
String s = ((ZipEntry)entries.nextElement()).getName();
if (s.endsWith(".class")) {
s = s.substring(0, s.length() - 6).replace('/', '.');
loader.loadClass(s);
}
}
t = System.currentTimeMillis() - t;
if (i == 0) {
perfs[step][mode] = t;
} else {
perfs[step][mode] = Math.min(perfs[step][mode], t);
}
switch (mode) {
case 0: System.out.print("NO ADAPT: "); break;
case 1: System.out.print("NULL ADAPT: "); break;
case 2: System.out.print("COMPUTE MAXS: "); break;
default: System.out.print("ADD COUNTER: "); break;
}
System.out.print((float)t + " ms ");
System.out.print("(" + total + " classes");
System.out.println(", " + totalSize + " bytes)");
loader = null;
gc();
}
}
if (step == 0) {
System.out.println("SECOND STEP: WITHOUT DEBUG INFORMATION");
}
}
// prints results
System.out.println("\nRESULTS");
System.out.println("\nWITH DEBUG INFORMATION\n");
for (int step = 0; step < 2; ++step) {
for (mode = 0; mode < 4; ++mode) {
switch (mode) {
case 0: System.out.print("NO ADAPT: "); break;
case 1: System.out.print("NULL ADAPT: "); break;
case 2: System.out.print("COMPUTE MAXS: "); break;
default: System.out.print("ADD COUNTER: "); break;
}
System.out.println((float)perfs[step][mode] + " ms");
}
if (step == 0) {
System.out.println("\nWITHOUT DEBUG INFORMATION\n");
}
}
}
protected Class findClass (final String name) throws ClassNotFoundException {
try {
byte[] b;
String fileName = name.replace('.', '/') + ".class";
InputStream is = zip.getInputStream(zip.getEntry(fileName));
switch (mode) {
case 0:
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;
}
break;
} else {
len += n;
if (len == b.length) {
byte[] c = new byte[b.length + 1000];
System.arraycopy(b, 0, c, 0, len);
b = c;
}
}
}
break;
case 1:
compute = false;
skipDebug = false;
b = nullAdaptClass(is, name);
break;
case 2:
compute = true;
skipDebug = false;
b = nullAdaptClass(is, name);
break;
case 3:
b = counterAdaptClass(is, name);
break;
//case 4:
default:
compute = false;
skipDebug = true;
b = nullAdaptClass(is, name);
break;
}
if (dst != null) {
dst.putNextEntry(new ZipEntry(fileName));
dst.write(b, 0, b.length);
dst.closeEntry();
}
total += 1;
totalSize += b.length;
return defineClass(name, b, 0, b.length);
} catch (Exception e) {
e.printStackTrace();
throw new ClassNotFoundException(name);
}
}
private static void gc () {
try {
Runtime.getRuntime().gc();
Thread.sleep(50);
Runtime.getRuntime().gc();
Thread.sleep(50);
Runtime.getRuntime().gc();
Thread.sleep(50);
} catch (InterruptedException e) {
}
}
abstract ALL newInstance ();
abstract byte[] nullAdaptClass (final InputStream is, final String name)
throws Exception;
abstract byte[] counterAdaptClass (final InputStream is, final String name)
throws Exception;
}