1*0ed15c77SAndroid Build Coastguard Worker package perf; 2*0ed15c77SAndroid Build Coastguard Worker 3*0ed15c77SAndroid Build Coastguard Worker import com.fasterxml.jackson.databind.ObjectMapper; 4*0ed15c77SAndroid Build Coastguard Worker import com.fasterxml.jackson.databind.ObjectWriter; 5*0ed15c77SAndroid Build Coastguard Worker import com.fasterxml.jackson.databind.SerializationFeature; 6*0ed15c77SAndroid Build Coastguard Worker 7*0ed15c77SAndroid Build Coastguard Worker abstract class ObjectWriterTestBase<T1,T2> 8*0ed15c77SAndroid Build Coastguard Worker { 9*0ed15c77SAndroid Build Coastguard Worker protected int hash; 10*0ed15c77SAndroid Build Coastguard Worker targetSizeMegs()11*0ed15c77SAndroid Build Coastguard Worker protected abstract int targetSizeMegs(); 12*0ed15c77SAndroid Build Coastguard Worker test(ObjectMapper mapper, String desc1, T1 inputValue1, Class<? extends T1> inputClass1, String desc2, T2 inputValue2, Class<? extends T2> inputClass2)13*0ed15c77SAndroid Build Coastguard Worker protected void test(ObjectMapper mapper, 14*0ed15c77SAndroid Build Coastguard Worker String desc1, T1 inputValue1, Class<? extends T1> inputClass1, 15*0ed15c77SAndroid Build Coastguard Worker String desc2, T2 inputValue2, Class<? extends T2> inputClass2) 16*0ed15c77SAndroid Build Coastguard Worker throws Exception 17*0ed15c77SAndroid Build Coastguard Worker { 18*0ed15c77SAndroid Build Coastguard Worker final int REPS; 19*0ed15c77SAndroid Build Coastguard Worker { 20*0ed15c77SAndroid Build Coastguard Worker final byte[] input1 = mapper.writeValueAsBytes(inputValue1); 21*0ed15c77SAndroid Build Coastguard Worker final byte[] input2 = mapper.writeValueAsBytes(inputValue2); 22*0ed15c77SAndroid Build Coastguard Worker 23*0ed15c77SAndroid Build Coastguard Worker // Let's try to guestimate suitable size, N megs of output 24*0ed15c77SAndroid Build Coastguard Worker REPS = (int) ((double) (targetSizeMegs() * 1000 * 1000) / (double) input1.length); 25*0ed15c77SAndroid Build Coastguard Worker System.out.printf("Read %d bytes to bind (%d as array); will do %d repetitions\n", 26*0ed15c77SAndroid Build Coastguard Worker input1.length, input2.length, REPS); 27*0ed15c77SAndroid Build Coastguard Worker } 28*0ed15c77SAndroid Build Coastguard Worker 29*0ed15c77SAndroid Build Coastguard Worker final ObjectWriter writer0 = mapper.writer().with(SerializationFeature.EAGER_SERIALIZER_FETCH); 30*0ed15c77SAndroid Build Coastguard Worker final ObjectWriter writer1 = writer0.forType(inputClass1); 31*0ed15c77SAndroid Build Coastguard Worker final ObjectWriter writer2 = writer0.forType(inputClass2); 32*0ed15c77SAndroid Build Coastguard Worker 33*0ed15c77SAndroid Build Coastguard Worker int i = 0; 34*0ed15c77SAndroid Build Coastguard Worker int roundsDone = 0; 35*0ed15c77SAndroid Build Coastguard Worker final int TYPES = 2; 36*0ed15c77SAndroid Build Coastguard Worker 37*0ed15c77SAndroid Build Coastguard Worker // Skip first 5 seconds 38*0ed15c77SAndroid Build Coastguard Worker long startMeasure = System.currentTimeMillis() + 5000L; 39*0ed15c77SAndroid Build Coastguard Worker System.out.print("Warming up"); 40*0ed15c77SAndroid Build Coastguard Worker 41*0ed15c77SAndroid Build Coastguard Worker final double[] timesMsec = new double[TYPES]; 42*0ed15c77SAndroid Build Coastguard Worker 43*0ed15c77SAndroid Build Coastguard Worker while (true) { 44*0ed15c77SAndroid Build Coastguard Worker final int round = (i % TYPES); 45*0ed15c77SAndroid Build Coastguard Worker final boolean lf = (++i % TYPES) == 0; 46*0ed15c77SAndroid Build Coastguard Worker 47*0ed15c77SAndroid Build Coastguard Worker String msg; 48*0ed15c77SAndroid Build Coastguard Worker 49*0ed15c77SAndroid Build Coastguard Worker ObjectWriter writer; 50*0ed15c77SAndroid Build Coastguard Worker Object value; 51*0ed15c77SAndroid Build Coastguard Worker switch (round) { 52*0ed15c77SAndroid Build Coastguard Worker case 0: 53*0ed15c77SAndroid Build Coastguard Worker msg = desc1; 54*0ed15c77SAndroid Build Coastguard Worker writer = writer1; 55*0ed15c77SAndroid Build Coastguard Worker value = inputValue1; 56*0ed15c77SAndroid Build Coastguard Worker break; 57*0ed15c77SAndroid Build Coastguard Worker case 1: 58*0ed15c77SAndroid Build Coastguard Worker msg = desc2; 59*0ed15c77SAndroid Build Coastguard Worker writer = writer2; 60*0ed15c77SAndroid Build Coastguard Worker value = inputValue2; 61*0ed15c77SAndroid Build Coastguard Worker break; 62*0ed15c77SAndroid Build Coastguard Worker default: 63*0ed15c77SAndroid Build Coastguard Worker throw new Error(); 64*0ed15c77SAndroid Build Coastguard Worker } 65*0ed15c77SAndroid Build Coastguard Worker 66*0ed15c77SAndroid Build Coastguard Worker double msecs = testSer(REPS, value, writer); 67*0ed15c77SAndroid Build Coastguard Worker 68*0ed15c77SAndroid Build Coastguard Worker // skip first N seconds to let results stabilize 69*0ed15c77SAndroid Build Coastguard Worker if (startMeasure > 0L) { 70*0ed15c77SAndroid Build Coastguard Worker if ((round != 0) || (System.currentTimeMillis() < startMeasure)) { 71*0ed15c77SAndroid Build Coastguard Worker System.out.print("."); 72*0ed15c77SAndroid Build Coastguard Worker continue; 73*0ed15c77SAndroid Build Coastguard Worker } 74*0ed15c77SAndroid Build Coastguard Worker startMeasure = 0L; 75*0ed15c77SAndroid Build Coastguard Worker System.out.println(); 76*0ed15c77SAndroid Build Coastguard Worker System.out.println("Starting measurements..."); 77*0ed15c77SAndroid Build Coastguard Worker Thread.sleep(250L); 78*0ed15c77SAndroid Build Coastguard Worker System.out.println(); 79*0ed15c77SAndroid Build Coastguard Worker } 80*0ed15c77SAndroid Build Coastguard Worker 81*0ed15c77SAndroid Build Coastguard Worker timesMsec[round] += msecs; 82*0ed15c77SAndroid Build Coastguard Worker 83*0ed15c77SAndroid Build Coastguard Worker if ((i % 17) == 0) { 84*0ed15c77SAndroid Build Coastguard Worker System.out.println("[GC]"); 85*0ed15c77SAndroid Build Coastguard Worker Thread.sleep(100L); 86*0ed15c77SAndroid Build Coastguard Worker System.gc(); 87*0ed15c77SAndroid Build Coastguard Worker Thread.sleep(100L); 88*0ed15c77SAndroid Build Coastguard Worker } 89*0ed15c77SAndroid Build Coastguard Worker 90*0ed15c77SAndroid Build Coastguard Worker System.out.printf("Test '%s' [hash: 0x%s] -> %.1f msecs\n", msg, hash, msecs); 91*0ed15c77SAndroid Build Coastguard Worker Thread.sleep(50L); 92*0ed15c77SAndroid Build Coastguard Worker if (!lf) { 93*0ed15c77SAndroid Build Coastguard Worker continue; 94*0ed15c77SAndroid Build Coastguard Worker } 95*0ed15c77SAndroid Build Coastguard Worker 96*0ed15c77SAndroid Build Coastguard Worker if ((++roundsDone % 3) == 0) { 97*0ed15c77SAndroid Build Coastguard Worker double den = (double) roundsDone; 98*0ed15c77SAndroid Build Coastguard Worker System.out.printf("Averages after %d rounds (%s/%s): %.1f / %.1f msecs\n", 99*0ed15c77SAndroid Build Coastguard Worker roundsDone, desc1, desc2, 100*0ed15c77SAndroid Build Coastguard Worker timesMsec[0] / den, timesMsec[1] / den); 101*0ed15c77SAndroid Build Coastguard Worker } 102*0ed15c77SAndroid Build Coastguard Worker System.out.println(); 103*0ed15c77SAndroid Build Coastguard Worker } 104*0ed15c77SAndroid Build Coastguard Worker } 105*0ed15c77SAndroid Build Coastguard Worker testSer(int REPS, Object value, ObjectWriter writer)106*0ed15c77SAndroid Build Coastguard Worker protected double testSer(int REPS, Object value, ObjectWriter writer) throws Exception 107*0ed15c77SAndroid Build Coastguard Worker { 108*0ed15c77SAndroid Build Coastguard Worker final NopOutputStream out = new NopOutputStream(); 109*0ed15c77SAndroid Build Coastguard Worker long start = System.nanoTime(); 110*0ed15c77SAndroid Build Coastguard Worker while (--REPS >= 0) { 111*0ed15c77SAndroid Build Coastguard Worker writer.writeValue(out, value); 112*0ed15c77SAndroid Build Coastguard Worker } 113*0ed15c77SAndroid Build Coastguard Worker hash = out.size(); 114*0ed15c77SAndroid Build Coastguard Worker long nanos = System.nanoTime() - start; 115*0ed15c77SAndroid Build Coastguard Worker out.close(); 116*0ed15c77SAndroid Build Coastguard Worker return _msecsFromNanos(nanos); 117*0ed15c77SAndroid Build Coastguard Worker } 118*0ed15c77SAndroid Build Coastguard Worker _msecsFromNanos(long nanos)119*0ed15c77SAndroid Build Coastguard Worker protected final double _msecsFromNanos(long nanos) { 120*0ed15c77SAndroid Build Coastguard Worker return (nanos / 1000000.0); 121*0ed15c77SAndroid Build Coastguard Worker } 122*0ed15c77SAndroid Build Coastguard Worker } 123