blob: 52d19d3948e3adcbb5a08b494812ec423e1e209a [file] [log] [blame]
import java.io.*;
import org.codehaus.jackson.*;
import org.codehaus.jackson.map.*;
public final class TestMapSpeed
{
/**
* Number of repetitions to run per test. Dynamically variable,
* based on observed runtime, to try to keep it high enough.
*/
private int REPS;
/**
* Let's keep per-run times above 50 milliseconds
*/
//final static int MIN_RUN_TIME = 50;
final static int MIN_RUN_TIME = 5;
/**
* Let's keep per-run times below 300 milliseconds
*/
//final static int MAX_RUN_TIME = 300;
final static int MAX_RUN_TIME = 1000;
private final static int TEST_PER_GC = 17;
final JsonFactory _factory;
final ObjectMapper _mapper;
final Object _objectToMap;
private TestMapSpeed(byte[] data)
throws Exception
{
_factory = new JsonFactory();
_mapper = new ObjectMapper();
JsonParser jp = _factory.createJsonParser(data, 0, data.length);
_objectToMap = _mapper.readValue(jp, Object.class);
jp.close();
// Ok how should we guestimate speed... perhaps from data size?
REPS = 100 + ((8 * 1000 * 1000) / data.length);
System.out.println("Based on size, will use "+REPS+" repetitions");
}
protected int test()
throws Exception
{
int i = 0;
int total = 0;
final int TEST_CASES = 2;
final ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);
while (true) {
try { Thread.sleep(150L); } catch (InterruptedException ie) { }
int round = (i++ % TEST_CASES);
long now = System.currentTimeMillis();
String msg;
int sum = 0;
//round = 1; // testing just old or new?
switch (round) {
case 0:
msg = "Map using OLD";
sum = testOld(REPS, bos);
break;
case 1:
msg = "Map using NEW";
sum = testNew(REPS, bos);
break;
default:
throw new Error("Internal error");
}
now = System.currentTimeMillis() - now;
if (round == 0) {
System.out.println();
}
System.out.println("Test '"+msg+"' -> "+now+" msecs ("
+sum+" -> "+(total & 0xFF)+").");
total += sum;
if ((i % TEST_PER_GC) == 0) {
System.out.println("[GC]");
try { Thread.sleep(100L); } catch (InterruptedException ie) { }
System.gc();
try { Thread.sleep(200L); } catch (InterruptedException ie) { }
/* One more tweak: let's add load if things start
* running too fast or slow, to try to get sweet range
* of 50 to 250 millisseconds
*/
if (now < MIN_RUN_TIME) {
REPS += (REPS / 5); // 20% up
System.out.println("[NOTE: increasing reps, now: "+REPS+"]");
try { Thread.sleep(200L); } catch (InterruptedException ie) { }
} else if (now > MAX_RUN_TIME && i > 20) {
/* Let's reduce load slower than increase; also,
* due to initial warmup, let's not adjust until
* we've gone through a few cycles
*/
REPS -= (REPS / 10); // 10% down
System.out.println("[NOTE: decreasing reps, now: "+REPS+"]");
try { Thread.sleep(200L); } catch (InterruptedException ie) { }
}
}
}
}
/*
/////////////////////////////////////////////////////////
// Actual value type access, ones via Stax 1.0
/////////////////////////////////////////////////////////
*/
protected int testOld(int reps, ByteArrayOutputStream out)
throws Exception
{
int total = 0;
for (int i = 0; i < reps; ++i) {
out.reset();
JsonGenerator jg = _factory.createJsonGenerator(out, JsonEncoding.UTF8);
_mapper.writeValue(jg, _objectToMap);
jg.close();
total = out.size();
}
return total;
}
protected int testNew(int reps, ByteArrayOutputStream out)
throws Exception
{
int total = 0;
for (int i = 0; i < reps; ++i) {
out.reset();
JsonGenerator jg = _factory.createJsonGenerator(out, JsonEncoding.UTF8);
_mapper.writeValue(jg, _objectToMap);
jg.close();
total = out.size();
}
return total;
}
/*
/////////////////////////////////////////////////////////
// Helper methods
/////////////////////////////////////////////////////////
*/
static byte[] readData(File file) throws IOException
{
InputStream fin = new FileInputStream(file);
byte[] buf = new byte[4000];
ByteArrayOutputStream bos = new ByteArrayOutputStream(4000);
int count;
while ((count = fin.read(buf)) > 0) {
bos.write(buf, 0, count);
}
fin.close();
return bos.toByteArray();
}
public static void main(String[] args)
throws Exception
{
if (args.length != 1) {
System.err.println("Usage: java ... <file>");
System.exit(1);
}
byte[] data = readData(new File(args[0]));
System.out.println(" -> "+data.length+" bytes read.");
new TestMapSpeed(data).test();
}
}