1 /* 2 * Copyright (C) 2011 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.google.gson.metrics; 17 18 import com.google.caliper.BeforeExperiment; 19 import com.google.gson.Gson; 20 import com.google.gson.stream.JsonReader; 21 import java.io.IOException; 22 import java.io.StringReader; 23 import java.lang.reflect.Field; 24 25 /** 26 * Caliper based micro benchmarks for Gson 27 * 28 * @author Inderjeet Singh 29 * @author Jesse Wilson 30 * @author Joel Leitch 31 */ 32 public class BagOfPrimitivesDeserializationBenchmark { 33 34 private Gson gson; 35 private String json; 36 main(String[] args)37 public static void main(String[] args) { 38 NonUploadingCaliperRunner.run(BagOfPrimitivesDeserializationBenchmark.class, args); 39 } 40 41 @BeforeExperiment setUp()42 void setUp() throws Exception { 43 this.gson = new Gson(); 44 BagOfPrimitives bag = new BagOfPrimitives(10L, 1, false, "foo"); 45 this.json = gson.toJson(bag); 46 } 47 48 /** 49 * Benchmark to measure Gson performance for deserializing an object 50 */ timeBagOfPrimitivesDefault(int reps)51 public void timeBagOfPrimitivesDefault(int reps) { 52 for (int i=0; i<reps; ++i) { 53 gson.fromJson(json, BagOfPrimitives.class); 54 } 55 } 56 57 /** 58 * Benchmark to measure deserializing objects by hand 59 */ timeBagOfPrimitivesStreaming(int reps)60 public void timeBagOfPrimitivesStreaming(int reps) throws IOException { 61 for (int i=0; i<reps; ++i) { 62 StringReader reader = new StringReader(json); 63 JsonReader jr = new JsonReader(reader); 64 jr.beginObject(); 65 long longValue = 0; 66 int intValue = 0; 67 boolean booleanValue = false; 68 String stringValue = null; 69 while(jr.hasNext()) { 70 String name = jr.nextName(); 71 if (name.equals("longValue")) { 72 longValue = jr.nextLong(); 73 } else if (name.equals("intValue")) { 74 intValue = jr.nextInt(); 75 } else if (name.equals("booleanValue")) { 76 booleanValue = jr.nextBoolean(); 77 } else if (name.equals("stringValue")) { 78 stringValue = jr.nextString(); 79 } else { 80 throw new IOException("Unexpected name: " + name); 81 } 82 } 83 jr.endObject(); 84 new BagOfPrimitives(longValue, intValue, booleanValue, stringValue); 85 } 86 } 87 88 /** 89 * This benchmark measures the ideal Gson performance: the cost of parsing a JSON stream and 90 * setting object values by reflection. We should strive to reduce the discrepancy between this 91 * and {@link #timeBagOfPrimitivesDefault(int)} . 92 */ timeBagOfPrimitivesReflectionStreaming(int reps)93 public void timeBagOfPrimitivesReflectionStreaming(int reps) throws Exception { 94 for (int i=0; i<reps; ++i) { 95 StringReader reader = new StringReader(json); 96 JsonReader jr = new JsonReader(reader); 97 jr.beginObject(); 98 BagOfPrimitives bag = new BagOfPrimitives(); 99 while(jr.hasNext()) { 100 String name = jr.nextName(); 101 for (Field field : BagOfPrimitives.class.getDeclaredFields()) { 102 if (field.getName().equals(name)) { 103 Class<?> fieldType = field.getType(); 104 if (fieldType.equals(long.class)) { 105 field.setLong(bag, jr.nextLong()); 106 } else if (fieldType.equals(int.class)) { 107 field.setInt(bag, jr.nextInt()); 108 } else if (fieldType.equals(boolean.class)) { 109 field.setBoolean(bag, jr.nextBoolean()); 110 } else if (fieldType.equals(String.class)) { 111 field.set(bag, jr.nextString()); 112 } else { 113 throw new RuntimeException("Unexpected: type: " + fieldType + ", name: " + name); 114 } 115 } 116 } 117 } 118 jr.endObject(); 119 } 120 } 121 } 122