Apply an ugly optimization to save 5% on pretty printed JSON documents. This uses locals instead of fields in an inner loop to save field reads and writes.

This commit is contained in:
Jesse Wilson 2011-12-14 05:26:29 +00:00
parent 40cd660115
commit aa52435951

View File

@ -854,8 +854,28 @@ public class JsonReader implements Closeable {
} }
private int nextNonWhitespace(boolean throwOnEof) throws IOException { private int nextNonWhitespace(boolean throwOnEof) throws IOException {
while (pos < limit || fillBuffer(1)) { /*
int c = buffer[pos++]; * This code uses ugly local variables 'p' and 'l' representing the 'pos'
* and 'limit' fields respectively. Using locals rather than fields saves
* a few field reads for each whitespace character in a pretty-printed
* document, resulting in a 5% speedup. We need to flush 'p' to its field
* before any (potentially indirect) call to fillBuffer() and reread both
* 'p' and 'l' after any (potentially indirect) call to the same method.
*/
char[] buffer = this.buffer;
int p = pos;
int l = limit;
while (true) {
if (p == l) {
pos = p;
if (!fillBuffer(1)) {
break;
}
p = pos;
l = limit;
}
int c = buffer[p++];
switch (c) { switch (c) {
case '\t': case '\t':
case ' ': case ' ':
@ -864,7 +884,8 @@ public class JsonReader implements Closeable {
continue; continue;
case '/': case '/':
if (pos == limit && !fillBuffer(1)) { pos = p;
if (p == l && !fillBuffer(1)) {
return c; return c;
} }
@ -877,13 +898,16 @@ public class JsonReader implements Closeable {
if (!skipTo("*/")) { if (!skipTo("*/")) {
throw syntaxError("Unterminated comment"); throw syntaxError("Unterminated comment");
} }
pos += 2; p = pos + 2;
l = limit;
continue; continue;
case '/': case '/':
// skip a // end-of-line comment // skip a // end-of-line comment
pos++; pos++;
skipToEndOfLine(); skipToEndOfLine();
p = pos;
l = limit;
continue; continue;
default: default:
@ -891,6 +915,7 @@ public class JsonReader implements Closeable {
} }
case '#': case '#':
pos = p;
/* /*
* Skip a # hash end-of-line comment. The JSON RFC doesn't * Skip a # hash end-of-line comment. The JSON RFC doesn't
* specify this behaviour, but it's required to parse * specify this behaviour, but it's required to parse
@ -898,9 +923,12 @@ public class JsonReader implements Closeable {
*/ */
checkLenient(); checkLenient();
skipToEndOfLine(); skipToEndOfLine();
p = pos;
l = limit;
continue; continue;
default: default:
pos = p;
return c; return c;
} }
} }