diff options
Diffstat (limited to 'gson/src/test/java/com/google/gson/metrics/PerformanceTest.java')
-rw-r--r-- | gson/src/test/java/com/google/gson/metrics/PerformanceTest.java | 346 |
1 files changed, 346 insertions, 0 deletions
diff --git a/gson/src/test/java/com/google/gson/metrics/PerformanceTest.java b/gson/src/test/java/com/google/gson/metrics/PerformanceTest.java new file mode 100644 index 00000000..cf444eee --- /dev/null +++ b/gson/src/test/java/com/google/gson/metrics/PerformanceTest.java @@ -0,0 +1,346 @@ +/* + * Copyright (C) 2008 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.gson.Gson; +import com.google.gson.JsonParseException; +import com.google.gson.annotations.Expose; +import com.google.gson.reflect.TypeToken; + +import junit.framework.TestCase; + +import java.io.StringWriter; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Tests to measure performance for Gson. All tests in this file will be disabled in code. To run + * them remove disabled_ prefix from the tests and run them. + * + * @author Inderjeet Singh + * @author Joel Leitch + */ +public class PerformanceTest extends TestCase { + private static final int COLLECTION_SIZE = 5000; + + private static final int NUM_ITERATIONS = 100; + + private Gson gson; + + @Override + protected void setUp() throws Exception { + super.setUp(); + gson = new Gson(); + } + + public void testDummy() { + // This is here to prevent Junit for complaining when we disable all tests. + } + + public void disabled_testStringDeserialization() { + StringBuilder sb = new StringBuilder(8096); + sb.append("Error Yippie"); + + while (true) { + try { + String stackTrace = sb.toString(); + sb.append(stackTrace); + String json = "{\"message\":\"Error message.\"," + "\"stackTrace\":\"" + stackTrace + "\"}"; + parseLongJson(json); + System.out.println("Gson could handle a string of size: " + stackTrace.length()); + } catch (JsonParseException expected) { + break; + } + } + } + + private void parseLongJson(String json) throws JsonParseException { + ExceptionHolder target = gson.fromJson(json, ExceptionHolder.class); + assertTrue(target.message.contains("Error")); + assertTrue(target.stackTrace.contains("Yippie")); + } + + private static class ExceptionHolder { + public final String message; + public final String stackTrace; + + // For use by Gson + @SuppressWarnings("unused") + private ExceptionHolder() { + this("", ""); + } + public ExceptionHolder(String message, String stackTrace) { + this.message = message; + this.stackTrace = stackTrace; + } + } + + @SuppressWarnings("unused") + private static class CollectionEntry { + final String name; + final String value; + + // For use by Gson + private CollectionEntry() { + this(null, null); + } + + CollectionEntry(String name, String value) { + this.name = name; + this.value = value; + } + } + + /** + * Created in response to http://code.google.com/p/google-gson/issues/detail?id=96 + */ + public void disabled_testLargeCollectionSerialization() { + int count = 1400000; + List<CollectionEntry> list = new ArrayList<CollectionEntry>(count); + for (int i = 0; i < count; ++i) { + list.add(new CollectionEntry("name"+i,"value"+i)); + } + gson.toJson(list); + } + + /** + * Created in response to http://code.google.com/p/google-gson/issues/detail?id=96 + */ + public void disabled_testLargeCollectionDeserialization() { + StringBuilder sb = new StringBuilder(); + int count = 87000; + boolean first = true; + sb.append('['); + for (int i = 0; i < count; ++i) { + if (first) { + first = false; + } else { + sb.append(','); + } + sb.append("{name:'name").append(i).append("',value:'value").append(i).append("'}"); + } + sb.append(']'); + String json = sb.toString(); + Type collectionType = new TypeToken<ArrayList<CollectionEntry>>(){}.getType(); + List<CollectionEntry> list = gson.fromJson(json, collectionType); + assertEquals(count, list.size()); + } + + /** + * Created in response to http://code.google.com/p/google-gson/issues/detail?id=96 + */ + // Last I tested, Gson was able to serialize upto 14MB byte array + public void disabled_testByteArraySerialization() { + for (int size = 4145152; true; size += 1036288) { + byte[] ba = new byte[size]; + for (int i = 0; i < size; ++i) { + ba[i] = 0x05; + } + gson.toJson(ba); + System.out.printf("Gson could serialize a byte array of size: %d\n", size); + } + } + + /** + * Created in response to http://code.google.com/p/google-gson/issues/detail?id=96 + */ + // Last I tested, Gson was able to deserialize a byte array of 11MB + public void disable_testByteArrayDeserialization() { + for (int numElements = 10639296; true; numElements += 16384) { + StringBuilder sb = new StringBuilder(numElements*2); + sb.append("["); + boolean first = true; + for (int i = 0; i < numElements; ++i) { + if (first) { + first = false; + } else { + sb.append(","); + } + sb.append("5"); + } + sb.append("]"); + String json = sb.toString(); + byte[] ba = gson.fromJson(json, byte[].class); + System.out.printf("Gson could deserialize a byte array of size: %d\n", ba.length); + } + } + +// The tests to measure serialization and deserialization performance of Gson +// Based on the discussion at +// http://groups.google.com/group/google-gson/browse_thread/thread/7a50b17a390dfaeb +// Test results: 10/19/2009 +// Serialize classes avg time: 60 ms +// Deserialized classes avg time: 70 ms +// Serialize exposed classes avg time: 159 ms +// Deserialized exposed classes avg time: 173 ms + + public void disabled_testSerializeClasses() { + ClassWithList c = new ClassWithList("str"); + for (int i = 0; i < COLLECTION_SIZE; ++i) { + c.list.add(new ClassWithField("element-" + i)); + } + StringWriter w = new StringWriter(); + long t1 = System.currentTimeMillis(); + for (int i = 0; i < NUM_ITERATIONS; ++i) { + gson.toJson(c, w); + } + long t2 = System.currentTimeMillis(); + long avg = (t2 - t1) / NUM_ITERATIONS; + System.out.printf("Serialize classes avg time: %d ms\n", avg); + } + + public void disabled_testDeserializeClasses() { + String json = buildJsonForClassWithList(); + ClassWithList[] target = new ClassWithList[NUM_ITERATIONS]; + long t1 = System.currentTimeMillis(); + for (int i = 0; i < NUM_ITERATIONS; ++i) { + target[i] = gson.fromJson(json, ClassWithList.class); + } + long t2 = System.currentTimeMillis(); + long avg = (t2 - t1) / NUM_ITERATIONS; + System.out.printf("Deserialize classes avg time: %d ms\n", avg); + } + + public void disable_testLargeObjectSerializationAndDeserialization() { + Map<String, Long> largeObject = new HashMap<String, Long>(); + for (long l = 0; l < 100000; l++) { + largeObject.put("field" + l, l); + } + + long t1 = System.currentTimeMillis(); + String json = gson.toJson(largeObject); + long t2 = System.currentTimeMillis(); + System.out.printf("Large object serialized in: %d ms\n", (t2 - t1)); + + t1 = System.currentTimeMillis(); + gson.fromJson(json, new TypeToken<Map<String, Long>>() {}.getType()); + t2 = System.currentTimeMillis(); + System.out.printf("Large object deserialized in: %d ms\n", (t2 - t1)); + + } + + public void disabled_testSerializeExposedClasses() { + ClassWithListOfObjects c1 = new ClassWithListOfObjects("str"); + for (int i1 = 0; i1 < COLLECTION_SIZE; ++i1) { + c1.list.add(new ClassWithExposedField("element-" + i1)); + } + ClassWithListOfObjects c = c1; + StringWriter w = new StringWriter(); + long t1 = System.currentTimeMillis(); + for (int i = 0; i < NUM_ITERATIONS; ++i) { + gson.toJson(c, w); + } + long t2 = System.currentTimeMillis(); + long avg = (t2 - t1) / NUM_ITERATIONS; + System.out.printf("Serialize exposed classes avg time: %d ms\n", avg); + } + + public void disabled_testDeserializeExposedClasses() { + String json = buildJsonForClassWithList(); + ClassWithListOfObjects[] target = new ClassWithListOfObjects[NUM_ITERATIONS]; + long t1 = System.currentTimeMillis(); + for (int i = 0; i < NUM_ITERATIONS; ++i) { + target[i] = gson.fromJson(json, ClassWithListOfObjects.class); + } + long t2 = System.currentTimeMillis(); + long avg = (t2 - t1) / NUM_ITERATIONS; + System.out.printf("Deserialize exposed classes avg time: %d ms\n", avg); + } + + public void disabled_testLargeGsonMapRoundTrip() throws Exception { + Map<Long, Long> original = new HashMap<Long, Long>(); + for (long i = 0; i < 1000000; i++) { + original.put(i, i + 1); + } + + Gson gson = new Gson(); + String json = gson.toJson(original); + Type longToLong = new TypeToken<Map<Long, Long>>(){}.getType(); + gson.fromJson(json, longToLong); + } + + private String buildJsonForClassWithList() { + StringBuilder sb = new StringBuilder("{"); + sb.append("field:").append("'str',"); + sb.append("list:["); + boolean first = true; + for (int i = 0; i < COLLECTION_SIZE; ++i) { + if (first) { + first = false; + } else { + sb.append(","); + } + sb.append("{field:'element-" + i + "'}"); + } + sb.append("]"); + sb.append("}"); + String json = sb.toString(); + return json; + } + + @SuppressWarnings("unused") + private static final class ClassWithList { + final String field; + final List<ClassWithField> list = new ArrayList<ClassWithField>(COLLECTION_SIZE); + ClassWithList() { + this(null); + } + ClassWithList(String field) { + this.field = field; + } + } + + @SuppressWarnings("unused") + private static final class ClassWithField { + final String field; + ClassWithField() { + this(""); + } + public ClassWithField(String field) { + this.field = field; + } + } + + @SuppressWarnings("unused") + private static final class ClassWithListOfObjects { + @Expose + final String field; + @Expose + final List<ClassWithExposedField> list = new ArrayList<ClassWithExposedField>(COLLECTION_SIZE); + ClassWithListOfObjects() { + this(null); + } + ClassWithListOfObjects(String field) { + this.field = field; + } + } + + @SuppressWarnings("unused") + private static final class ClassWithExposedField { + @Expose + final String field; + ClassWithExposedField() { + this(""); + } + ClassWithExposedField(String field) { + this.field = field; + } + } +} |