| package perf; |
| |
| import java.io.*; |
| import java.util.*; |
| |
| import com.fasterxml.jackson.core.type.TypeReference; |
| import com.fasterxml.jackson.databind.*; |
| |
| /** |
| * Variant that uses hard-coded input but compares cost of generic type |
| * resolution to that of passing raw (type-erased) Class. |
| * |
| * @since 2.8 |
| */ |
| public class ManualReadWithTypeResolution |
| { |
| private final String _desc1, _desc2; |
| private final byte[] _input; |
| private final Class<?> _inputType; |
| private final TypeReference<?> _inputTypeRef; |
| |
| private final ObjectMapper _mapper; |
| private final int REPS; |
| |
| protected int hash; |
| // wait for 3 seconds |
| protected long startMeasure = System.currentTimeMillis() + 3000L; |
| protected int roundsDone = 0; |
| private double[] timeMsecs; |
| |
| public static void main(String[] args) throws Exception { |
| new ManualReadWithTypeResolution().doTest(); |
| } |
| |
| private ManualReadWithTypeResolution() throws IOException { |
| _desc1 = "Raw type"; |
| _desc2 = "Generic type"; |
| _mapper = new ObjectMapper(); |
| |
| _input = "[\"value\",\"123\"]".getBytes("UTF-8"); |
| _inputType = List.class; |
| _inputTypeRef = new TypeReference<List<String>>() { }; |
| |
| /* |
| _input = "{\"id\":124}".getBytes("UTF-8"); |
| _inputType = Map.class; |
| _inputTypeRef = new TypeReference<Map<String,Object>>() { }; |
| */ |
| |
| REPS = (int) ((double) (15 * 1000 * 1000) / (double) _input.length); |
| } |
| |
| // When comparing to simple streaming parsing, uncomment: |
| |
| private void doTest() throws Exception |
| { |
| |
| System.out.printf("Read %d bytes to bind; will do %d repetitions\n", |
| _input.length, REPS); |
| System.out.print("Warming up"); |
| |
| int i = 0; |
| final int TYPES = 2; |
| |
| |
| timeMsecs = new double[TYPES]; |
| |
| while (true) { |
| Thread.sleep(100L); |
| final int type = (i++ % TYPES); |
| |
| String msg; |
| double msesc; |
| |
| switch (type) { |
| case 0: |
| msesc = testDeser(REPS, _input, _mapper, _inputType); |
| msg = _desc1; |
| break; |
| case 1: |
| msesc = testDeser(REPS, _input, _mapper, _inputTypeRef); |
| msg = _desc2; |
| break; |
| default: |
| throw new Error(); |
| } |
| updateStats(type, (i % 17) == 0, msg, msesc); |
| } |
| } |
| |
| protected final double testDeser(int reps, byte[] json, ObjectMapper mapper, Class<?> type) |
| throws IOException |
| { |
| long start = System.nanoTime(); |
| Object result = null; |
| while (--reps >= 0) { |
| result = mapper.readValue(json, type); |
| } |
| hash = result.hashCode(); |
| return _msecsFromNanos(System.nanoTime() - start); |
| } |
| |
| protected final double testDeser(int reps, byte[] json, ObjectMapper mapper, TypeReference<?> type) |
| throws IOException |
| { |
| long start = System.nanoTime(); |
| Object result = null; |
| while (--reps >= 0) { |
| result = mapper.readValue(json, type); |
| } |
| hash = result.hashCode(); |
| return _msecsFromNanos(System.nanoTime() - start); |
| } |
| |
| private void updateStats(int type, boolean doGc, String msg, double msecs) |
| throws Exception |
| { |
| final boolean lf = (type == (timeMsecs.length - 1)); |
| |
| if (startMeasure == 0L) { // skip first N seconds |
| timeMsecs[type] += msecs; |
| } else { |
| if (lf) { |
| if (System.currentTimeMillis() >= startMeasure) { |
| startMeasure = 0L; |
| System.out.println(" complete!"); |
| } else { |
| System.out.print("."); |
| } |
| } |
| return; |
| } |
| |
| System.out.printf("Test '%s' [hash: 0x%s] -> %.1f msecs\n", msg, Integer.toHexString(hash), msecs); |
| if (lf) { |
| ++roundsDone; |
| if ((roundsDone % 3) == 0 ) { |
| double den = (double) roundsDone; |
| System.out.printf("Averages after %d rounds (%s/%s): %.1f / %.1f msecs\n", |
| (int) den, _desc1, _desc2, |
| timeMsecs[0] / den, timeMsecs[1] / den); |
| } |
| System.out.println(); |
| } |
| if (doGc) { |
| System.out.println("[GC]"); |
| Thread.sleep(100L); |
| System.gc(); |
| Thread.sleep(100L); |
| } |
| } |
| |
| protected final double _msecsFromNanos(long nanos) { |
| return (nanos / 1000000.0); |
| } |
| } |