package de.jpaw.bonaparte.benchmark.core; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Date; import com.google.gson.Gson; import de.jpaw.bonaparte.core.BonaPortable; import de.jpaw.bonaparte.core.ByteArrayComposer; import de.jpaw.bonaparte.core.ByteArrayParser; import de.jpaw.bonaparte.core.CompactComposer; import de.jpaw.bonaparte.core.MessageParser; import de.jpaw.bonaparte.core.MessageParserException; import de.jpaw.bonaparte.core.StringBuilderComposer; import de.jpaw.bonaparte.core.StringBuilderParser; import de.jpaw.util.ByteArray; public class OneThread implements Runnable { private final int method; private final int callsPerThread; private final int initialBufferSize; private Date start; private Date stop; private String methodName = "?"; private BonaPortable src; private byte [] srcdata; private byte [] srcExternalized; private byte [] srcCompact; private String gsondata; private Class<? extends BonaPortable> srcClass; // this is required by Gson OneThread(BonaPortable src, int method, int millionCallsPerThread, int initialBufferSize) { this.src = src; this.method = method; this.callsPerThread = millionCallsPerThread * 1000000; this.initialBufferSize = initialBufferSize; } private void createSources() throws IOException { // create serialized Bonaparte object StringBuilderComposer sbc = new StringBuilderComposer(new StringBuilder(initialBufferSize)); sbc.writeRecord(src); srcdata = sbc.getBytes(); // create serialized object ByteArrayOutputStream fos = new ByteArrayOutputStream(1000); ObjectOutputStream o = new ObjectOutputStream(fos); o.writeObject(src); o.flush(); o.close(); srcExternalized = fos.toByteArray(); // create serialized object (compact) fos = new ByteArrayOutputStream(1000); DataOutputStream o2 = new DataOutputStream(fos); CompactComposer cc = new CompactComposer(o2, false); cc.writeRecord(src); o2.flush(); o2.close(); srcCompact = fos.toByteArray(); // create serialized JSON object for Gson Gson gson = new Gson(); gsondata = gson.toJson(src); srcClass = src.getClass(); } // StringBuffer private void sbc(boolean retrieveBytes) { methodName = "Bonaparte StringBuilder Composer" + (retrieveBytes ? " with byte[] retrieval" : ""); StringBuilderComposer sbc = new StringBuilderComposer(new StringBuilder(initialBufferSize)); for (int i = 0; i < callsPerThread; ++i) { sbc.reset(); sbc.writeRecord(src); if (retrieveBytes) { @SuppressWarnings("unused") byte [] sbcResult = sbc.getBytes(); } } } private void sbp() throws MessageParserException { methodName = "Bonaparte StringBuilder Parser"; for (int i = 0; i < callsPerThread; ++i) { StringBuilder work = new StringBuilder(new String(srcdata, ByteArray.CHARSET_UTF8)); MessageParser<MessageParserException> w1 = new StringBuilderParser(work, 0, -1); @SuppressWarnings("unused") BonaPortable dst1 = w1.readRecord(); } } // ByteArray private void bac(boolean retrieveBytes) { methodName = "Bonaparte ByteArray Composer" + (retrieveBytes ? " with byte[] retrieval" : ""); ByteArrayComposer bac = new ByteArrayComposer(); for (int i = 0; i < callsPerThread; ++i) { bac.reset(); bac.writeRecord(src); if (retrieveBytes) { @SuppressWarnings("unused") byte [] bacResult = bac.getBytes(); } } } // ByteArray private void coc(boolean retrieveBytes) throws IOException { methodName = "Bonaparte Compact Composer" + (retrieveBytes ? " with byte[] retrieval" : ""); ByteArrayOutputStream fos = new ByteArrayOutputStream(1000); DataOutputStream o2 = new DataOutputStream(fos); CompactComposer cc = new CompactComposer(o2, false); for (int i = 0; i < callsPerThread; ++i) { cc.reset(); cc.writeRecord(src); o2.flush(); if (retrieveBytes) { @SuppressWarnings("unused") byte [] bacResult = fos.toByteArray(); } fos.reset(); } } // ByteArray private void cocId(boolean retrieveBytes) throws IOException { methodName = "Bonaparte Compact Composer" + (retrieveBytes ? " with byte[] retrieval" : ""); ByteArrayOutputStream fos = new ByteArrayOutputStream(1000); DataOutputStream o2 = new DataOutputStream(fos); CompactComposer cc = new CompactComposer(o2, true); for (int i = 0; i < callsPerThread; ++i) { cc.reset(); cc.writeRecord(src); o2.flush(); if (retrieveBytes) { @SuppressWarnings("unused") byte [] bacResult = fos.toByteArray(); } fos.reset(); } } private void bap() throws MessageParserException { methodName = "Bonaparte ByteArray Parser"; for (int i = 0; i < callsPerThread; ++i) { MessageParser<MessageParserException> w2 = new ByteArrayParser(srcdata, 0, -1); @SuppressWarnings("unused") BonaPortable dst2 = w2.readRecord(); } } // Externalizer private void extc(boolean retrieveBytes) throws IOException { methodName = "Bonaparte Externalizer Composer" + (retrieveBytes ? " with byte[] retrieval" : ""); for (int i = 0; i < callsPerThread; ++i) { ByteArrayOutputStream fos = new ByteArrayOutputStream(1000); ObjectOutputStream o = new ObjectOutputStream(fos); o.writeObject(src); o.close(); if (retrieveBytes) { @SuppressWarnings("unused") byte[] extcResult = fos.toByteArray(); } } } private void extp() throws MessageParserException, IOException, ClassNotFoundException { methodName = "Bonaparte Externalizer Parser"; for (int i = 0; i < callsPerThread; ++i) { ByteArrayInputStream fis = new ByteArrayInputStream(srcExternalized); ObjectInputStream in = new ObjectInputStream(fis); @SuppressWarnings("unused") Object xdst = in.readObject(); } } // Gson private void toGson(boolean retrieveBytes) { methodName = "Gson composer" + (retrieveBytes ? " with byte[] retrieval" : ""); Gson gson = new Gson(); for (int i = 0; i < callsPerThread; ++i) { String result = gson.toJson(src); if (retrieveBytes) { @SuppressWarnings("unused") byte [] bacResult = result.getBytes(); } } } private void fromGson() { methodName = "Gson Parser"; Gson gson = new Gson(); for (int i = 0; i < callsPerThread; ++i) { @SuppressWarnings("unused") BonaPortable dst = gson.fromJson(gsondata, srcClass); // BonaPortable.class results in an exception } } @Override public void run() { try { createSources(); start = new Date(); switch (method) { // 0 .. 2 Bonaparte StringBuffer case 0: sbc(false); break; case 1: sbc(true); break; case 2: sbp(); break; // 10..12 Bonaparte ByteArray case 10: bac(false); break; case 11: bac(true); break; case 12: bap(); break; // 20..22 Bonaparte Externalizer case 20: extc(false); break; case 21: extc(true); break; case 22: extp(); break; // 30..32 Bonaparte compact case 30: coc(false); break; case 31: coc(true); break; case 32: // cop(); break; // 40..42 Bonaparte compact with Ids instead of class names case 40: cocId(false); break; case 41: cocId(true); break; case 42: // cop(); break; // 100 .. 102 Gson (String) case 100: toGson(false); break; case 101: toGson(true); break; case 102: fromGson(); break; } } catch (Exception e) { e.printStackTrace(); System.out.println("Exception: " + methodName + " did not finish"); return; } stop = new Date(); long millis = stop.getTime() - start.getTime(); double callsPerMilliSecond = callsPerThread / millis; System.out.println("Thread result: " + (int)callsPerMilliSecond + " k calls / second for " + methodName + " (= " + callsPerThread + " in " + millis + " milliseconds)"); } }