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