| 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(); | 
 |     } | 
 | } |