package mil.navy.nps.testing; import mil.navy.nps.dis.*; import java.net.*; import java.io.*; /** Benchmarker code

This is some thrown-together test harness code to figure out just how fast we can do some things in java. There are various tests for instantiation speed, how fast objects can be serialized/deserialized, and so on.

HISTORY 25Oct96 DMcG New */ class Benchmark extends Object { public static void main(String args[]) throws UnknownHostException, SocketException, UnknownHostException, IOException { int idx = 0; EntityStatePdu aPdu, anotherPdu; long time1 = 0, time2 = 0, timeDifference = 0; int instantiateCount; byte outputBuffer[] = new byte[1500]; // buffer to hold datagram data ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); DataOutputStream dataOutputStream = new DataOutputStream(outputStream); DatagramSocket dgramSocket; // socket to spit it out on DatagramPacket dgramPacket; // one datagram packet InetAddress dgramDest; // destination internet address byte byteArray[]; // serialized bytes String destMachine = new String("devo.cs.nps.navy.mil"); // machine to send packets to String destSocketNumber = new String("8242"); // socket number on remote machine to send to String sendSocketNumber = new String("8242"); // socket we use on this machine to send out data String iterations = new String("5000"); // number of iterations to perform boolean instantiate = false; boolean clone = false; boolean send = true; for(idx = 0; idx < args.length; idx++) { if((args[idx].equals("-h")) || (args[idx].equals("-?") ) ) { System.out.println("Command line options: "); System.out.println(" -destMachine machine to send to"); System.out.println(" -destSockNo remote socket to write to"); System.out.println(" -sendSockNo Socket to use on this machine to send"); System.out.println(" -iterations Number of test iterations to perform"); System.out.println(" -instantiate Run object instantiation benchmarks"); System.out.println(" -clone Run object cloning benchmarks"); System.out.println(" -send Run datagram sending benchmarks"); return; } if(args[idx].equals("-destSockNo")) { destSocketNumber = args[idx+1]; System.out.println("got command line arg of -destSockNo with value of " + destSocketNumber); } if(args[idx].equals("-destMachine")) { destMachine = args[idx+1]; System.out.println("got command line arg of -destMachine with value of " + destMachine); } if(args[idx].equals("-sendSockNo")) { sendSocketNumber = args[idx+1]; System.out.println("got command line arg of -sendSockNo with value of " + sendSocketNumber); } if(args[idx].equals("-iterations")) { iterations = args[idx+1]; System.out.println("got command line arg of -iterations with value of " + iterations); } if(args[idx].equals("-instantiate")) { System.out.println("got command line arg of -instantiate; running instantiation tests "); instantiate = true; } if(args[idx].equals("-clone")) { System.out.println("got command line arg of -clone; running clone tests "); clone = true; } if(args[idx].equals("-send")) { System.out.println("got command line arg of -send; running send tests "); send = true; } } instantiateCount = Integer.valueOf(iterations).intValue(); if(instantiate) { time1 = System.currentTimeMillis(); // This is not all that great, since GC is involved in this too. // time required to instantiate X ESPDUs. This is mostly useful for // determining what the main bottlenecks are. for(idx = 0; idx < instantiateCount; idx++) aPdu = new EntityStatePdu(); time2 = System.currentTimeMillis(); timeDifference = time2 - time1; System.out.println("Milliseconds to instantiate " + instantiateCount + " EntityStatePdus is " + timeDifference); } // end of instantiate // full garbage collection to get rid of the objects above Benchmark.fullGC(); if(clone) { // time required to clone a new instance of an ESPDU. Compare this to the // time required to create a new PDU. aPdu = new EntityStatePdu(); time1 = System.currentTimeMillis(); for(idx = 0; idx < instantiateCount; idx++) anotherPdu = (EntityStatePdu)aPdu.clone(); time2 = System.currentTimeMillis(); timeDifference = time2 - time1; System.out.println("Milliseconds to clone " + instantiateCount + " EntityStatePdus is " + timeDifference); // do a full GC to wipe out all unreferenced objects and to make benchmarks more consistent. } // clone Benchmark.fullGC(); /* // Time required to serialize things to a stream aPdu = new EntityStatePdu(); time1 = System.currentTimeMillis(); // this does a bunch of stream construction, but I don't see an easy way around that right now... for(idx = 0; idx < instantiateCount; idx++) { outputStream.reset(); // set to beginning of data stream dataOutputStream = new DataOutputStream(outputStream); // create new data output stream aPdu.serialize(dataOutputStream); } time2 = System.currentTimeMillis(); timeDifference = time2 - time1; System.out.println("Milliseconds to serialize " + instantiateCount + " EntityStatePdus is " + timeDifference); */ // make things neat for benchmark Benchmark.fullGC(); // Try to write these things to a socket as fast as possible. Create a single // datagram packet, then repeatedly send that to a socket destination. aPdu = new EntityStatePdu(); dgramSocket = new DatagramSocket(Integer.valueOf(sendSocketNumber).intValue()); dgramDest = InetAddress.getByName(destMachine); dgramPacket = new DatagramPacket(outputBuffer, 1500, dgramDest, Integer.valueOf(destSocketNumber).intValue()); outputStream.reset(); dataOutputStream = new DataOutputStream(outputStream); aPdu.serialize(dataOutputStream); dgramPacket = new DatagramPacket(outputStream.toByteArray(), outputStream.size(), dgramDest, Integer.valueOf(destSocketNumber).intValue()); byteArray = outputStream.toByteArray(); System.out.println("size of pdu = " + byteArray.length); time1 = System.currentTimeMillis(); for(idx = 0; idx < instantiateCount; idx++) dgramSocket.send(dgramPacket); time2 = System.currentTimeMillis(); timeDifference = time2 - time1; System.out.println("Milliseconds to send " + instantiateCount + " datagram packets is " + timeDifference); return; } public static void fullGC() { // This is from Arnold & Gosling, P. 260. It runs GC until there's no increase in // free memory, which means we've collected all the garbage we can. A single call // to rt.gc does not neccesarily collect all garbage. This guarantees that we've // freed all the memory we can. Runtime rt = Runtime.getRuntime(); long isFree = rt.freeMemory(); long wasFree; do { wasFree = isFree; rt.gc(); isFree = rt.freeMemory(); } while (isFree > wasFree); rt.runFinalization(); } } // end of class Benchmark