aboutsummaryrefslogtreecommitdiffstats
path: root/metrics/src/main/java/com/google
diff options
context:
space:
mode:
Diffstat (limited to 'metrics/src/main/java/com/google')
-rw-r--r--metrics/src/main/java/com/google/gson/metrics/BagOfPrimitives.java95
-rw-r--r--metrics/src/main/java/com/google/gson/metrics/BagOfPrimitivesDeserializationBenchmark.java123
-rw-r--r--metrics/src/main/java/com/google/gson/metrics/CollectionsDeserializationBenchmark.java140
-rw-r--r--metrics/src/main/java/com/google/gson/metrics/ParseBenchmark.java389
-rw-r--r--metrics/src/main/java/com/google/gson/metrics/ParseBenchmarkData.zipbin0 -> 67881 bytes
-rw-r--r--metrics/src/main/java/com/google/gson/metrics/SerializationBenchmark.java53
6 files changed, 800 insertions, 0 deletions
diff --git a/metrics/src/main/java/com/google/gson/metrics/BagOfPrimitives.java b/metrics/src/main/java/com/google/gson/metrics/BagOfPrimitives.java
new file mode 100644
index 00000000..72cd6b6d
--- /dev/null
+++ b/metrics/src/main/java/com/google/gson/metrics/BagOfPrimitives.java
@@ -0,0 +1,95 @@
+/*
+ * 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;
+
+/**
+ * Class with a bunch of primitive fields
+ *
+ * @author Inderjeet Singh
+ */
+public class BagOfPrimitives {
+ public static final long DEFAULT_VALUE = 0;
+ public long longValue;
+ public int intValue;
+ public boolean booleanValue;
+ public String stringValue;
+
+ public BagOfPrimitives() {
+ this(DEFAULT_VALUE, 0, false, "");
+ }
+
+ public BagOfPrimitives(long longValue, int intValue, boolean booleanValue, String stringValue) {
+ this.longValue = longValue;
+ this.intValue = intValue;
+ this.booleanValue = booleanValue;
+ this.stringValue = stringValue;
+ }
+
+ public int getIntValue() {
+ return intValue;
+ }
+
+ public String getExpectedJson() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("{");
+ sb.append("\"longValue\":").append(longValue).append(",");
+ sb.append("\"intValue\":").append(intValue).append(",");
+ sb.append("\"booleanValue\":").append(booleanValue).append(",");
+ sb.append("\"stringValue\":\"").append(stringValue).append("\"");
+ sb.append("}");
+ return sb.toString();
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + (booleanValue ? 1231 : 1237);
+ result = prime * result + intValue;
+ result = prime * result + (int) (longValue ^ (longValue >>> 32));
+ result = prime * result + ((stringValue == null) ? 0 : stringValue.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ BagOfPrimitives other = (BagOfPrimitives) obj;
+ if (booleanValue != other.booleanValue)
+ return false;
+ if (intValue != other.intValue)
+ return false;
+ if (longValue != other.longValue)
+ return false;
+ if (stringValue == null) {
+ if (other.stringValue != null)
+ return false;
+ } else if (!stringValue.equals(other.stringValue))
+ return false;
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("(longValue=%d,intValue=%d,booleanValue=%b,stringValue=%s)",
+ longValue, intValue, booleanValue, stringValue);
+ }
+}
diff --git a/metrics/src/main/java/com/google/gson/metrics/BagOfPrimitivesDeserializationBenchmark.java b/metrics/src/main/java/com/google/gson/metrics/BagOfPrimitivesDeserializationBenchmark.java
new file mode 100644
index 00000000..8e6ea2b2
--- /dev/null
+++ b/metrics/src/main/java/com/google/gson/metrics/BagOfPrimitivesDeserializationBenchmark.java
@@ -0,0 +1,123 @@
+/*
+ * 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 com.google.caliper.Runner;
+import com.google.caliper.SimpleBenchmark;
+import com.google.gson.Gson;
+import com.google.gson.stream.JsonReader;
+
+/**
+ * Caliper based micro benchmarks for Gson
+ *
+ * @author Inderjeet Singh
+ * @author Jesse Wilson
+ * @author Joel Leitch
+ */
+public class BagOfPrimitivesDeserializationBenchmark extends SimpleBenchmark {
+
+ private Gson gson;
+ private String json;
+
+ public static void main(String[] args) {
+ Runner.main(BagOfPrimitivesDeserializationBenchmark.class, args);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ this.gson = new Gson();
+ BagOfPrimitives bag = new BagOfPrimitives(10L, 1, false, "foo");
+ this.json = gson.toJson(bag);
+ }
+
+ /**
+ * Benchmark to measure Gson performance for deserializing an object
+ */
+ public void timeBagOfPrimitivesDefault(int reps) {
+ for (int i=0; i<reps; ++i) {
+ gson.fromJson(json, BagOfPrimitives.class);
+ }
+ }
+
+ /**
+ * Benchmark to measure deserializing objects by hand
+ */
+ public void timeBagOfPrimitivesStreaming(int reps) throws IOException {
+ for (int i=0; i<reps; ++i) {
+ StringReader reader = new StringReader(json);
+ JsonReader jr = new JsonReader(reader);
+ 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();
+ new BagOfPrimitives(longValue, intValue, booleanValue, stringValue);
+ }
+ }
+
+ /**
+ * 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 #timeBagOfPrimitivesDefault(int)} .
+ */
+ public void timeBagOfPrimitivesReflectionStreaming(int reps) throws Exception {
+ for (int i=0; i<reps; ++i) {
+ StringReader reader = new StringReader(json);
+ JsonReader jr = new JsonReader(reader);
+ 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();
+ }
+ }
+}
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<List<BagOfPrimitives>>(){}.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<BagOfPrimitives> bags = new ArrayList<BagOfPrimitives>();
+ 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<reps; ++i) {
+ gson.fromJson(json, LIST_TYPE);
+ }
+ }
+
+ /**
+ * Benchmark to measure deserializing objects by hand
+ */
+ public void timeCollectionsStreaming(int reps) throws IOException {
+ for (int i=0; i<reps; ++i) {
+ StringReader reader = new StringReader(json);
+ JsonReader jr = new JsonReader(reader);
+ jr.beginArray();
+ List<BagOfPrimitives> bags = new ArrayList<BagOfPrimitives>();
+ 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<reps; ++i) {
+ StringReader reader = new StringReader(json);
+ JsonReader jr = new JsonReader(reader);
+ jr.beginArray();
+ List<BagOfPrimitives> bags = new ArrayList<BagOfPrimitives>();
+ 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/ParseBenchmark.java b/metrics/src/main/java/com/google/gson/metrics/ParseBenchmark.java
new file mode 100644
index 00000000..68134372
--- /dev/null
+++ b/metrics/src/main/java/com/google/gson/metrics/ParseBenchmark.java
@@ -0,0 +1,389 @@
+/*
+ * 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;
+import com.google.gson.JsonParser;
+import com.google.gson.annotations.SerializedName;
+import com.google.gson.reflect.TypeToken;
+import java.io.CharArrayReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.lang.reflect.Type;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+import org.codehaus.jackson.JsonFactory;
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.DeserializationConfig;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.type.TypeReference;
+
+/**
+ * Measure Gson and Jackson parsing and binding performance.
+ *
+ * <p>This benchmark requires that ParseBenchmarkData.zip is on the classpath.
+ * That file contains Twitter feed data, which is representative of what
+ * applications will be parsing.
+ */
+public final class ParseBenchmark extends SimpleBenchmark {
+ @Param Document document;
+ @Param Api api;
+
+ private enum Document {
+ TWEETS(new TypeToken<List<Tweet>>() {}, new TypeReference<List<Tweet>>() {}),
+ READER_SHORT(new TypeToken<Feed>() {}, new TypeReference<Feed>() {}),
+ READER_LONG(new TypeToken<Feed>() {}, new TypeReference<Feed>() {});
+
+ private final Type gsonType;
+ private final TypeReference<?> jacksonType;
+
+ private Document(TypeToken<?> typeToken, TypeReference<?> typeReference) {
+ this.gsonType = typeToken.getType();
+ this.jacksonType = typeReference;
+ }
+ }
+
+ private enum Api {
+ JACKSON_STREAM {
+ @Override Parser newParser() {
+ return new JacksonStreamParser();
+ }
+ },
+ JACKSON_BIND {
+ @Override Parser newParser() {
+ return new JacksonBindParser();
+ }
+ },
+ GSON_STREAM {
+ @Override Parser newParser() {
+ return new GsonStreamParser();
+ }
+ },
+ GSON_SKIP {
+ @Override Parser newParser() {
+ return new GsonSkipParser();
+ }
+ },
+ GSON_DOM {
+ @Override Parser newParser() {
+ return new GsonDomParser();
+ }
+ },
+ GSON_BIND {
+ @Override Parser newParser() {
+ return new GsonBindParser();
+ }
+ };
+ abstract Parser newParser();
+ }
+
+ private char[] text;
+ private Parser parser;
+
+ @Override protected void setUp() throws Exception {
+ text = resourceToString("/" + document.name() + ".json").toCharArray();
+ parser = api.newParser();
+ }
+
+ public void timeParse(int reps) throws Exception {
+ for (int i = 0; i < reps; i++) {
+ parser.parse(text, document);
+ }
+ }
+
+ private static String resourceToString(String path) throws Exception {
+ InputStream in = ParseBenchmark.class.getResourceAsStream(path);
+ if (in == null) {
+ throw new IllegalArgumentException("No such file: " + path);
+ }
+
+ Reader reader = new InputStreamReader(in, "UTF-8");
+ char[] buffer = new char[8192];
+ StringWriter writer = new StringWriter();
+ int count;
+ while ((count = reader.read(buffer)) != -1) {
+ writer.write(buffer, 0, count);
+ }
+ reader.close();
+ return writer.toString();
+ }
+
+ public static void main(String[] args) throws Exception {
+ Runner.main(ParseBenchmark.class, args);
+ }
+
+ interface Parser {
+ void parse(char[] data, Document document) throws Exception;
+ }
+
+ private static class GsonStreamParser implements Parser {
+ public void parse(char[] data, Document document) throws Exception {
+ com.google.gson.stream.JsonReader jsonReader
+ = new com.google.gson.stream.JsonReader(new CharArrayReader(data));
+ readToken(jsonReader);
+ jsonReader.close();
+ }
+
+ private void readToken(com.google.gson.stream.JsonReader reader) throws IOException {
+ while (true) {
+ switch (reader.peek()) {
+ case BEGIN_ARRAY:
+ reader.beginArray();
+ break;
+ case END_ARRAY:
+ reader.endArray();
+ break;
+ case BEGIN_OBJECT:
+ reader.beginObject();
+ break;
+ case END_OBJECT:
+ reader.endObject();
+ break;
+ case NAME:
+ reader.nextName();
+ break;
+ case BOOLEAN:
+ reader.nextBoolean();
+ break;
+ case NULL:
+ reader.nextNull();
+ break;
+ case NUMBER:
+ reader.nextLong();
+ break;
+ case STRING:
+ reader.nextString();
+ break;
+ case END_DOCUMENT:
+ return;
+ default:
+ throw new IllegalArgumentException("Unexpected token" + reader.peek());
+ }
+ }
+ }
+ }
+
+ private static class GsonSkipParser implements Parser {
+ public void parse(char[] data, Document document) throws Exception {
+ com.google.gson.stream.JsonReader jsonReader
+ = new com.google.gson.stream.JsonReader(new CharArrayReader(data));
+ jsonReader.skipValue();
+ jsonReader.close();
+ }
+ }
+
+ private static class JacksonStreamParser implements Parser {
+ public void parse(char[] data, Document document) throws Exception {
+ JsonFactory jsonFactory = new JsonFactory();
+ org.codehaus.jackson.JsonParser jp = jsonFactory.createJsonParser(new CharArrayReader(data));
+ jp.configure(org.codehaus.jackson.JsonParser.Feature.CANONICALIZE_FIELD_NAMES, false);
+ int depth = 0;
+ do {
+ switch (jp.nextToken()) {
+ case START_OBJECT:
+ case START_ARRAY:
+ depth++;
+ break;
+ case END_OBJECT:
+ case END_ARRAY:
+ depth--;
+ break;
+ case FIELD_NAME:
+ jp.getCurrentName();
+ break;
+ case VALUE_STRING:
+ jp.getText();
+ break;
+ case VALUE_NUMBER_INT:
+ case VALUE_NUMBER_FLOAT:
+ jp.getLongValue();
+ break;
+ }
+ } while (depth > 0);
+ jp.close();
+ }
+ }
+
+ private static class GsonDomParser implements Parser {
+ public void parse(char[] data, Document document) throws Exception {
+ new JsonParser().parse(new CharArrayReader(data));
+ }
+ }
+
+ private static class GsonBindParser implements Parser {
+ private static Gson gson = new GsonBuilder()
+ .setDateFormat("EEE MMM dd HH:mm:ss Z yyyy")
+ .create();
+
+ public void parse(char[] data, Document document) throws Exception {
+ gson.fromJson(new CharArrayReader(data), document.gsonType);
+ }
+ }
+
+ private static class JacksonBindParser implements Parser {
+ private static ObjectMapper mapper = new ObjectMapper();
+
+ static {
+ mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ mapper.configure(DeserializationConfig.Feature.AUTO_DETECT_FIELDS, true);
+ mapper.setDateFormat(new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy"));
+ }
+
+ public void parse(char[] data, Document document) throws Exception {
+ mapper.readValue(new CharArrayReader(data), document.jacksonType);
+ }
+ }
+
+ static class Tweet {
+ @JsonProperty String coordinates;
+ @JsonProperty boolean favorited;
+ @JsonProperty Date created_at;
+ @JsonProperty boolean truncated;
+ @JsonProperty Tweet retweeted_status;
+ @JsonProperty String id_str;
+ @JsonProperty String in_reply_to_id_str;
+ @JsonProperty String contributors;
+ @JsonProperty String text;
+ @JsonProperty long id;
+ @JsonProperty String retweet_count;
+ @JsonProperty String in_reply_to_status_id_str;
+ @JsonProperty Object geo;
+ @JsonProperty boolean retweeted;
+ @JsonProperty String in_reply_to_user_id;
+ @JsonProperty String in_reply_to_screen_name;
+ @JsonProperty Object place;
+ @JsonProperty User user;
+ @JsonProperty String source;
+ @JsonProperty String in_reply_to_user_id_str;
+ }
+
+ static class User {
+ @JsonProperty String name;
+ @JsonProperty String profile_sidebar_border_color;
+ @JsonProperty boolean profile_background_tile;
+ @JsonProperty String profile_sidebar_fill_color;
+ @JsonProperty Date created_at;
+ @JsonProperty String location;
+ @JsonProperty String profile_image_url;
+ @JsonProperty boolean follow_request_sent;
+ @JsonProperty String profile_link_color;
+ @JsonProperty boolean is_translator;
+ @JsonProperty String id_str;
+ @JsonProperty int favourites_count;
+ @JsonProperty boolean contributors_enabled;
+ @JsonProperty String url;
+ @JsonProperty boolean default_profile;
+ @JsonProperty long utc_offset;
+ @JsonProperty long id;
+ @JsonProperty boolean profile_use_background_image;
+ @JsonProperty int listed_count;
+ @JsonProperty String lang;
+ @JsonProperty("protected") @SerializedName("protected") boolean isProtected;
+ @JsonProperty int followers_count;
+ @JsonProperty String profile_text_color;
+ @JsonProperty String profile_background_color;
+ @JsonProperty String time_zone;
+ @JsonProperty String description;
+ @JsonProperty boolean notifications;
+ @JsonProperty boolean geo_enabled;
+ @JsonProperty boolean verified;
+ @JsonProperty String profile_background_image_url;
+ @JsonProperty boolean defalut_profile_image;
+ @JsonProperty int friends_count;
+ @JsonProperty int statuses_count;
+ @JsonProperty String screen_name;
+ @JsonProperty boolean following;
+ @JsonProperty boolean show_all_inline_media;
+ }
+
+ static class Feed {
+ @JsonProperty String id;
+ @JsonProperty String title;
+ @JsonProperty String description;
+ @JsonProperty("alternate") @SerializedName("alternate") List<Link> alternates;
+ @JsonProperty long updated;
+ @JsonProperty List<Item> items;
+
+ @Override public String toString() {
+ StringBuilder result = new StringBuilder()
+ .append(id)
+ .append("\n").append(title)
+ .append("\n").append(description)
+ .append("\n").append(alternates)
+ .append("\n").append(updated);
+ int i = 1;
+ for (Item item : items) {
+ result.append(i++).append(": ").append(item).append("\n\n");
+ }
+ return result.toString();
+ }
+ }
+
+ static class Link {
+ @JsonProperty String href;
+
+ @Override public String toString() {
+ return href;
+ }
+ }
+
+ static class Item {
+ @JsonProperty List<String> categories;
+ @JsonProperty String title;
+ @JsonProperty long published;
+ @JsonProperty long updated;
+ @JsonProperty("alternate") @SerializedName("alternate") List<Link> alternates;
+ @JsonProperty Content content;
+ @JsonProperty String author;
+ @JsonProperty List<ReaderUser> likingUsers;
+
+ @Override public String toString() {
+ return title
+ + "\nauthor: " + author
+ + "\npublished: " + published
+ + "\nupdated: " + updated
+ + "\n" + content
+ + "\nliking users: " + likingUsers
+ + "\nalternates: " + alternates
+ + "\ncategories: " + categories;
+ }
+ }
+
+ static class Content {
+ @JsonProperty String content;
+
+ @Override public String toString() {
+ return content;
+ }
+ }
+
+ static class ReaderUser {
+ @JsonProperty String userId;
+
+ @Override public String toString() {
+ return userId;
+ }
+ }
+}
diff --git a/metrics/src/main/java/com/google/gson/metrics/ParseBenchmarkData.zip b/metrics/src/main/java/com/google/gson/metrics/ParseBenchmarkData.zip
new file mode 100644
index 00000000..58e08bb5
--- /dev/null
+++ b/metrics/src/main/java/com/google/gson/metrics/ParseBenchmarkData.zip
Binary files differ
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<reps; ++i) {
+ gson.toJson(bag);
+ }
+ }
+}