summaryrefslogtreecommitdiffstats
path: root/core/tests
diff options
context:
space:
mode:
authorJesse Wilson <jessewilson@google.com>2010-11-17 17:46:42 -0800
committerJesse Wilson <jessewilson@google.com>2010-11-18 23:06:50 -0800
commit9d9b4e70a1e7f9ffb6cedd8a86fdd926f2a28202 (patch)
treeeb3e42e394a5b9e35f8ef40614815a591d421336 /core/tests
parent762b33f9494ba48aa1be3701d345b692e8432af9 (diff)
downloadframeworks_base-9d9b4e70a1e7f9ffb6cedd8a86fdd926f2a28202.zip
frameworks_base-9d9b4e70a1e7f9ffb6cedd8a86fdd926f2a28202.tar.gz
frameworks_base-9d9b4e70a1e7f9ffb6cedd8a86fdd926f2a28202.tar.bz2
Decode JSON literal types eagerly and with our own decoder.
Previously we relied on Double.parseDouble() to decode tokens. Since that method is expensive, we deferred calling it unless absolutely necessary. Now we decode the literal type immediately. For efficiency we decode the token right out of the char buffer. This makes things more complicated but it saves many calls to charAt(). With this change overall performance is 7% faster for JSON documents cited in the bug. benchmark run ms linear runtime % GsonParseFull no switch, no int parse 309 ============================ 93% GsonParseFull baseline 330 ============================== 100% http://b/3201883 Change-Id: I436b6769956b1357a17c807a327d3a234691c73f
Diffstat (limited to 'core/tests')
-rw-r--r--core/tests/coretests/src/android/util/JsonReaderTest.java159
1 files changed, 145 insertions, 14 deletions
diff --git a/core/tests/coretests/src/android/util/JsonReaderTest.java b/core/tests/coretests/src/android/util/JsonReaderTest.java
index ced9310..216a772 100644
--- a/core/tests/coretests/src/android/util/JsonReaderTest.java
+++ b/core/tests/coretests/src/android/util/JsonReaderTest.java
@@ -16,6 +16,7 @@
package android.util;
+import java.util.Arrays;
import junit.framework.TestCase;
import java.io.IOException;
@@ -23,6 +24,8 @@ import java.io.StringReader;
public final class JsonReaderTest extends TestCase {
+ private static final int READER_BUFFER_SIZE = 1024;
+
public void testReadArray() throws IOException {
JsonReader reader = new JsonReader(new StringReader("[true, true]"));
reader.beginArray();
@@ -178,7 +181,13 @@ public final class JsonReaderTest extends TestCase {
+ "-0.5,"
+ "2.2250738585072014E-308,"
+ "3.141592653589793,"
- + "2.718281828459045]";
+ + "2.718281828459045,"
+ + "\"1.0\","
+ + "\"011.0\","
+ + "\"NaN\","
+ + "\"Infinity\","
+ + "\"-Infinity\""
+ + "]";
JsonReader reader = new JsonReader(new StringReader(json));
reader.beginArray();
assertEquals(-0.0, reader.nextDouble());
@@ -190,19 +199,98 @@ public final class JsonReaderTest extends TestCase {
assertEquals(2.2250738585072014E-308, reader.nextDouble());
assertEquals(3.141592653589793, reader.nextDouble());
assertEquals(2.718281828459045, reader.nextDouble());
+ assertEquals(1,0, reader.nextDouble());
+ assertEquals(11.0, reader.nextDouble());
+ assertTrue(Double.isNaN(reader.nextDouble()));
+ assertEquals(Double.POSITIVE_INFINITY, reader.nextDouble());
+ assertEquals(Double.NEGATIVE_INFINITY, reader.nextDouble());
reader.endArray();
assertEquals(JsonToken.END_DOCUMENT, reader.peek());
}
- public void testNonFiniteDoubles() throws IOException {
- String json = "[NaN]";
+ public void testLenientDoubles() throws IOException {
+ String json = "["
+ + "011.0,"
+ + "NaN,"
+ + "NAN,"
+ + "Infinity,"
+ + "INFINITY,"
+ + "-Infinity"
+ + "]";
JsonReader reader = new JsonReader(new StringReader(json));
+ reader.setLenient(true);
reader.beginArray();
+ assertEquals(11.0, reader.nextDouble());
+ assertTrue(Double.isNaN(reader.nextDouble()));
+ try {
+ reader.nextDouble();
+ fail();
+ } catch (NumberFormatException expected) {
+ }
+ assertEquals("NAN", reader.nextString());
+ assertEquals(Double.POSITIVE_INFINITY, reader.nextDouble());
try {
reader.nextDouble();
fail();
} catch (NumberFormatException expected) {
}
+ assertEquals("INFINITY", reader.nextString());
+ assertEquals(Double.NEGATIVE_INFINITY, reader.nextDouble());
+ reader.endArray();
+ assertEquals(JsonToken.END_DOCUMENT, reader.peek());
+ }
+
+ public void testBufferBoundary() throws IOException {
+ char[] pad = new char[READER_BUFFER_SIZE - 8];
+ Arrays.fill(pad, '5');
+ String json = "[\"" + new String(pad) + "\",33333]";
+ JsonReader reader = new JsonReader(new StringReader(json));
+ reader.beginArray();
+ assertEquals(JsonToken.STRING, reader.peek());
+ assertEquals(new String(pad), reader.nextString());
+ assertEquals(JsonToken.NUMBER, reader.peek());
+ assertEquals(33333, reader.nextInt());
+ }
+
+ public void testTruncatedBufferBoundary() throws IOException {
+ char[] pad = new char[READER_BUFFER_SIZE - 8];
+ Arrays.fill(pad, '5');
+ String json = "[\"" + new String(pad) + "\",33333";
+ JsonReader reader = new JsonReader(new StringReader(json));
+ reader.setLenient(true);
+ reader.beginArray();
+ assertEquals(JsonToken.STRING, reader.peek());
+ assertEquals(new String(pad), reader.nextString());
+ assertEquals(JsonToken.NUMBER, reader.peek());
+ assertEquals(33333, reader.nextInt());
+ try {
+ reader.endArray();
+ fail();
+ } catch (IOException e) {
+ }
+ }
+
+ public void testLongestSupportedNumericLiterals() throws IOException {
+ testLongNumericLiterals(READER_BUFFER_SIZE - 1, JsonToken.NUMBER);
+ }
+
+ public void testLongerNumericLiterals() throws IOException {
+ testLongNumericLiterals(READER_BUFFER_SIZE, JsonToken.STRING);
+ }
+
+ private void testLongNumericLiterals(int length, JsonToken expectedToken) throws IOException {
+ char[] longNumber = new char[length];
+ Arrays.fill(longNumber, '9');
+ longNumber[0] = '1';
+ longNumber[1] = '.';
+
+ String json = "[" + new String(longNumber) + "]";
+ JsonReader reader = new JsonReader(new StringReader(json));
+ reader.setLenient(true);
+ reader.beginArray();
+ assertEquals(expectedToken, reader.peek());
+ assertEquals(2.0d, reader.nextDouble());
+ reader.endArray();
}
public void testLongs() throws IOException {
@@ -210,7 +298,13 @@ public final class JsonReaderTest extends TestCase {
+ "1,1,1,"
+ "-1,-1,-1,"
+ "-9223372036854775808,"
- + "9223372036854775807]";
+ + "9223372036854775807,"
+ + "5.0,"
+ + "1.0e2,"
+ + "\"011\","
+ + "\"5.0\","
+ + "\"1.0e2\""
+ + "]";
JsonReader reader = new JsonReader(new StringReader(json));
reader.beginArray();
assertEquals(0L, reader.nextLong());
@@ -234,6 +328,11 @@ public final class JsonReaderTest extends TestCase {
} catch (NumberFormatException expected) {
}
assertEquals(Long.MAX_VALUE, reader.nextLong());
+ assertEquals(5, reader.nextLong());
+ assertEquals(100, reader.nextLong());
+ assertEquals(11, reader.nextLong());
+ assertEquals(5, reader.nextLong());
+ assertEquals(100, reader.nextLong());
reader.endArray();
assertEquals(JsonToken.END_DOCUMENT, reader.peek());
}
@@ -250,28 +349,60 @@ public final class JsonReaderTest extends TestCase {
reader.endArray();
}
- public void testNumberWithOctalPrefix() throws IOException {
- String json = "[01]";
+ public void testMatchingValidNumbers() throws IOException {
+ String json = "[-1,99,-0,0,0e1,0e+1,0e-1,0E1,0E+1,0E-1,0.0,1.0,-1.0,1.0e0,1.0e+1,1.0e-1]";
+ JsonReader reader = new JsonReader(new StringReader(json));
+ reader.beginArray();
+ for (int i = 0; i < 16; i++) {
+ assertEquals(JsonToken.NUMBER, reader.peek());
+ reader.nextDouble();
+ }
+ reader.endArray();
+ }
+
+ public void testRecognizingInvalidNumbers() throws IOException {
+ String json = "[-00,00,001,+1,1f,0x,0xf,0x0,0f1,0ee1,1..0,1e0.1,1.-01,1.+1,1.0x,1.0+]";
+ JsonReader reader = new JsonReader(new StringReader(json));
+ reader.setLenient(true);
+ reader.beginArray();
+ for (int i = 0; i < 16; i++) {
+ assertEquals(JsonToken.STRING, reader.peek());
+ reader.nextString();
+ }
+ reader.endArray();
+ }
+
+ public void testNonFiniteDouble() throws IOException {
+ String json = "[NaN]";
JsonReader reader = new JsonReader(new StringReader(json));
reader.beginArray();
try {
- reader.nextInt();
+ reader.nextDouble();
fail();
- } catch (NumberFormatException expected) {
+ } catch (IOException expected) {
}
+ }
+
+ public void testNumberWithHexPrefix() throws IOException {
+ String json = "[0x11]";
+ JsonReader reader = new JsonReader(new StringReader(json));
+ reader.beginArray();
try {
reader.nextLong();
fail();
- } catch (NumberFormatException expected) {
+ } catch (IOException expected) {
}
+ }
+
+ public void testNumberWithOctalPrefix() throws IOException {
+ String json = "[01]";
+ JsonReader reader = new JsonReader(new StringReader(json));
+ reader.beginArray();
try {
- reader.nextDouble();
+ reader.nextInt();
fail();
- } catch (NumberFormatException expected) {
+ } catch (IOException expected) {
}
- assertEquals("01", reader.nextString());
- reader.endArray();
- assertEquals(JsonToken.END_DOCUMENT, reader.peek());
}
public void testBooleans() throws IOException {