diff --git a/metrics/src/main/java/com/google/gson/metrics/GsonBenchmark.java b/metrics/src/main/java/com/google/gson/metrics/BagOfPrimitivesDeserializationBenchmark.java similarity index 53% rename from metrics/src/main/java/com/google/gson/metrics/GsonBenchmark.java rename to metrics/src/main/java/com/google/gson/metrics/BagOfPrimitivesDeserializationBenchmark.java index a8600da4..8e6ea2b2 100644 --- a/metrics/src/main/java/com/google/gson/metrics/GsonBenchmark.java +++ b/metrics/src/main/java/com/google/gson/metrics/BagOfPrimitivesDeserializationBenchmark.java @@ -17,12 +17,11 @@ package com.google.gson.metrics; import java.io.IOException; import java.io.StringReader; +import java.lang.reflect.Field; -import com.google.caliper.Param; import com.google.caliper.Runner; import com.google.caliper.SimpleBenchmark; import com.google.gson.Gson; -import com.google.gson.GsonBuilder; import com.google.gson.stream.JsonReader; /** @@ -32,38 +31,35 @@ import com.google.gson.stream.JsonReader; * @author Jesse Wilson * @author Joel Leitch */ -public class GsonBenchmark extends SimpleBenchmark { +public class BagOfPrimitivesDeserializationBenchmark extends SimpleBenchmark { private Gson gson; - private BagOfPrimitives bag; private String json; - @Param - private boolean pretty; public static void main(String[] args) { - Runner.main(GsonBenchmark.class, args); + Runner.main(BagOfPrimitivesDeserializationBenchmark.class, args); } @Override protected void setUp() throws Exception { - this.gson = pretty ? new GsonBuilder().setPrettyPrinting().create() : new Gson(); - this.bag = new BagOfPrimitives(10L, 1, false, "foo"); + this.gson = new Gson(); + BagOfPrimitives bag = new BagOfPrimitives(10L, 1, false, "foo"); this.json = gson.toJson(bag); } - public void timeObjectSerialization(int reps) { - for (int i=0; i fieldType = field.getType(); + if (fieldType.equals(long.class)) { + field.setLong(bag, jr.nextLong()); + } else if (fieldType.equals(int.class)) { + field.setInt(bag, jr.nextInt()); + } else if (fieldType.equals(boolean.class)) { + field.setBoolean(bag, jr.nextBoolean()); + } else if (fieldType.equals(String.class)) { + field.set(bag, jr.nextString()); + } else { + throw new RuntimeException("Unexpected: type: " + fieldType + ", name: " + name); + } + } + } + } + jr.endObject(); + } + } } diff --git a/metrics/src/main/java/com/google/gson/metrics/CollectionsDeserializationBenchmark.java b/metrics/src/main/java/com/google/gson/metrics/CollectionsDeserializationBenchmark.java new file mode 100644 index 00000000..09a5782a --- /dev/null +++ b/metrics/src/main/java/com/google/gson/metrics/CollectionsDeserializationBenchmark.java @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2011 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.gson.metrics; + +import java.io.IOException; +import java.io.StringReader; +import java.lang.reflect.Field; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; + +import com.google.caliper.Runner; +import com.google.caliper.SimpleBenchmark; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import com.google.gson.stream.JsonReader; + +/** + * Caliper based micro benchmarks for Gson + * + * @author Inderjeet Singh + */ +public class CollectionsDeserializationBenchmark extends SimpleBenchmark { + + private static final Type LIST_TYPE = new TypeToken>(){}.getType(); + private Gson gson; + private String json; + + public static void main(String[] args) { + Runner.main(CollectionsDeserializationBenchmark.class, args); + } + + @Override + protected void setUp() throws Exception { + this.gson = new Gson(); + List bags = new ArrayList(); + for (int i = 0; i < 100; ++i) { + bags.add(new BagOfPrimitives(10L, 1, false, "foo")); + } + this.json = gson.toJson(bags, LIST_TYPE); + } + + /** + * Benchmark to measure Gson performance for deserializing an object + */ + public void timeCollectionsDefault(int reps) { + for (int i=0; i bags = new ArrayList(); + while(jr.hasNext()) { + jr.beginObject(); + long longValue = 0; + int intValue = 0; + boolean booleanValue = false; + String stringValue = null; + while(jr.hasNext()) { + String name = jr.nextName(); + if (name.equals("longValue")) { + longValue = jr.nextLong(); + } else if (name.equals("intValue")) { + intValue = jr.nextInt(); + } else if (name.equals("booleanValue")) { + booleanValue = jr.nextBoolean(); + } else if (name.equals("stringValue")) { + stringValue = jr.nextString(); + } else { + throw new IOException("Unexpected name: " + name); + } + } + jr.endObject(); + bags.add(new BagOfPrimitives(longValue, intValue, booleanValue, stringValue)); + } + jr.endArray(); + } + } + + /** + * This benchmark measures the ideal Gson performance: the cost of parsing a JSON stream and + * setting object values by reflection. We should strive to reduce the discrepancy between this + * and {@link #timeCollectionsDefault(int)} . + */ + public void timeCollectionsReflectionStreaming(int reps) throws Exception { + for (int i=0; i bags = new ArrayList(); + while(jr.hasNext()) { + jr.beginObject(); + BagOfPrimitives bag = new BagOfPrimitives(); + while(jr.hasNext()) { + String name = jr.nextName(); + for (Field field : BagOfPrimitives.class.getDeclaredFields()) { + if (field.getName().equals(name)) { + Class fieldType = field.getType(); + if (fieldType.equals(long.class)) { + field.setLong(bag, jr.nextLong()); + } else if (fieldType.equals(int.class)) { + field.setInt(bag, jr.nextInt()); + } else if (fieldType.equals(boolean.class)) { + field.setBoolean(bag, jr.nextBoolean()); + } else if (fieldType.equals(String.class)) { + field.set(bag, jr.nextString()); + } else { + throw new RuntimeException("Unexpected: type: " + fieldType + ", name: " + name); + } + } + } + } + jr.endObject(); + bags.add(bag); + } + jr.endArray(); + } + } +} diff --git a/metrics/src/main/java/com/google/gson/metrics/SerializationBenchmark.java b/metrics/src/main/java/com/google/gson/metrics/SerializationBenchmark.java new file mode 100644 index 00000000..9cdf085e --- /dev/null +++ b/metrics/src/main/java/com/google/gson/metrics/SerializationBenchmark.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2011 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.gson.metrics; + +import com.google.caliper.Param; +import com.google.caliper.Runner; +import com.google.caliper.SimpleBenchmark; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +/** + * Caliper based micro benchmarks for Gson serialization + * + * @author Inderjeet Singh + * @author Jesse Wilson + * @author Joel Leitch + */ +public class SerializationBenchmark extends SimpleBenchmark { + + private Gson gson; + private BagOfPrimitives bag; + @Param + private boolean pretty; + + public static void main(String[] args) { + Runner.main(SerializationBenchmark.class, args); + } + + @Override + protected void setUp() throws Exception { + this.gson = pretty ? new GsonBuilder().setPrettyPrinting().create() : new Gson(); + this.bag = new BagOfPrimitives(10L, 1, false, "foo"); + } + + public void timeObjectSerialization(int reps) { + for (int i=0; i