improved performance

This commit is contained in:
高铁
2016-04-04 22:51:04 +08:00
parent ac69ccf432
commit c7ba79bdee
6 changed files with 415 additions and 73 deletions
@@ -169,7 +169,10 @@ public class DefaultJSONParser implements Closeable {
try {
boolean setContextFlag = false;
for (;;) {
lexer.skipWhitespace();
if (lexer.ch != '"' && lexer.ch != '}') {
lexer.skipWhitespace();
}
char ch = lexer.ch;
if ((lexer.features & Feature.AllowArbitraryCommas.mask) != 0) {
while (ch == ',') {
@@ -180,18 +183,33 @@ public class DefaultJSONParser implements Closeable {
}
boolean isObjectKey = false;
boolean strKey = false;
String keyStr = null;
Object key;
if (ch == '"') {
key = lexer.scanSymbol(symbolTable, '"');
lexer.skipWhitespace();
key = keyStr = lexer.scanSymbol(symbolTable, '"');
strKey = true;
if (lexer.ch != ':') {
lexer.skipWhitespace();
}
ch = lexer.ch;
if (ch != ':') {
throw new JSONException("expect ':' at " + lexer.pos + ", name " + key);
}
} else if (ch == '}') {
lexer.next();
lexer.resetStringPosition();
lexer.nextToken();
// lexer.next();
{
int index = ++lexer.bp;
if (index >= lexer.len) {
lexer.ch = EOI;
} else {
lexer.ch = lexer.text.charAt(index);
}
}
lexer.sp = 0; // resetStringPosition
lexer.nextToken(JSONToken.COMMA);
return object;
} else if (ch == '\'') {
if ((lexer.features & Feature.AllowSingleQuotes.mask) == 0) {
@@ -199,7 +217,9 @@ public class DefaultJSONParser implements Closeable {
}
key = lexer.scanSymbol(symbolTable, '\'');
lexer.skipWhitespace();
if (lexer.ch != ':') {
lexer.skipWhitespace();
}
ch = lexer.ch;
if (ch != ':') {
throw new JSONException("expect ':' at " + lexer.pos);
@@ -209,7 +229,7 @@ public class DefaultJSONParser implements Closeable {
} else if (ch == ',') {
throw new JSONException("syntax error");
} else if ((ch >= '0' && ch <= '9') || ch == '-') {
lexer.resetStringPosition();
lexer.sp = 0; // resetStringPosition
lexer.scanNumber();
if (lexer.token == JSONToken.LITERAL_INT) {
key = lexer.integerValue();
@@ -238,13 +258,29 @@ public class DefaultJSONParser implements Closeable {
}
if (!isObjectKey) {
lexer.next();
lexer.skipWhitespace();
// lexer.next();
{
int index = ++lexer.bp;
if (index >= lexer.len) {
lexer.ch = EOI;
} else {
lexer.ch = lexer.text.charAt(index);
}
}
// lexer.skipWhitespace();
for (;;) {
if (lexer.ch == ' ' || lexer.ch == '\n' || lexer.ch == '\r' || lexer.ch == '\t' || lexer.ch == '\f' || lexer.ch == '\b') {
lexer.next();
} else {
break;
}
}
}
ch = lexer.ch;
lexer.resetStringPosition();
lexer.sp = 0; // lexer.resetStringPosition();
if (key == JSON.DEFAULT_TYPE_KEY) {
String typeName = lexer.scanSymbol(symbolTable, '"');
@@ -350,8 +386,12 @@ public class DefaultJSONParser implements Closeable {
setContextFlag = true;
}
if (object.getClass() == JSONObject.class) {
key = (key == null) ? "null" : key.toString();
if (object instanceof JSONObject) {
if (key == null) {
key = "null";
} else {
key = strKey ? keyStr : key.toString();
}
}
Object value;
@@ -387,7 +427,7 @@ public class DefaultJSONParser implements Closeable {
object.put(key, value);
if (lexer.token == JSONToken.RBRACE) {
lexer.nextToken();
lexer.nextToken(JSONToken.COMMA);
return object;
} else if (lexer.token == JSONToken.COMMA) {
continue;
@@ -395,9 +435,9 @@ public class DefaultJSONParser implements Closeable {
throw new JSONException("syntax error");
}
} else if (ch == '{') { // 减少嵌套,兼容android
lexer.nextToken();
lexer.nextToken(JSONToken.LITERAL_STRING);
final boolean parentIsArray = fieldName != null && fieldName.getClass() == Integer.class;
final boolean parentIsArray = fieldName != null && fieldName instanceof Integer;
JSONObject input = new JSONObject();
ParseContext ctxLocal = null;
@@ -411,10 +451,10 @@ public class DefaultJSONParser implements Closeable {
ctxLocal.object = object;
}
checkMapResolve(object, key.toString());
checkMapResolve(object, strKey ? keyStr : key.toString());
if (object.getClass() == JSONObject.class) {
object.put(key.toString(), obj);
if (object instanceof JSONObject) {
object.put(strKey ? keyStr : key.toString(), obj);
} else {
object.put(key, obj);
}
@@ -424,7 +464,7 @@ public class DefaultJSONParser implements Closeable {
}
if (lexer.token == JSONToken.RBRACE) {
lexer.nextToken();
lexer.nextToken(JSONToken.COMMA);
setContext(context);
return object;
@@ -452,15 +492,34 @@ public class DefaultJSONParser implements Closeable {
}
}
lexer.skipWhitespace();
if (lexer.ch != ',' && lexer.ch != '}') {
lexer.skipWhitespace();
}
ch = lexer.ch;
if (ch == ',') {
lexer.next();
// lexer.next();
{
int index = ++lexer.bp;
if (index >= lexer.len) {
lexer.ch = EOI;
} else {
lexer.ch = lexer.text.charAt(index);
}
}
continue;
} else if (ch == '}') {
lexer.next();
lexer.resetStringPosition();
lexer.nextToken();
// lexer.next();
{
int index = ++lexer.bp;
if (index >= lexer.len) {
lexer.ch = EOI;
} else {
lexer.ch = lexer.text.charAt(index);
}
}
lexer.sp = 0; // lexer.resetStringPosition();
lexer.nextToken(JSONToken.COMMA);
this.setContext(object, fieldName);
@@ -111,7 +111,15 @@ public final class JSONLexer {
len = text.length();
bp = -1;
next();
// next();
{
int index = ++bp;
if (index >= len) {
ch = EOI;
} else {
ch = text.charAt(index);
}
}
if (ch == 65279) {
next();
}
@@ -270,7 +278,15 @@ public final class JSONLexer {
token = RPAREN;
return;
case '[':
next();
// next();
{
int index = ++bp;
if (index >= len) {
ch = EOI;
} else {
ch = text.charAt(index);
}
}
token = LBRACKET;
return;
case ']':
@@ -278,11 +294,27 @@ public final class JSONLexer {
token = RBRACKET;
return;
case '{':
next();
// next();
{
int index = ++bp;
if (index >= len) {
ch = EOI;
} else {
ch = text.charAt(index);
}
}
token = LBRACE;
return;
case '}':
next();
// next();
{
int index = ++bp;
if (index >= len) {
ch = EOI;
} else {
ch = text.charAt(index);
}
}
token = RBRACE;
return;
case ':':
@@ -317,7 +349,15 @@ public final class JSONLexer {
case JSONToken.LBRACE:
if (ch == '{') {
token = JSONToken.LBRACE;
next();
// next();
{
int index = ++bp;
if (index >= len) {
ch = EOI;
} else {
ch = text.charAt(index);
}
}
return;
}
if (ch == '[') {
@@ -329,19 +369,43 @@ public final class JSONLexer {
case JSONToken.COMMA:
if (ch == ',') {
token = JSONToken.COMMA;
next();
// next();
{
int index = ++bp;
if (index >= len) {
ch = EOI;
} else {
ch = text.charAt(index);
}
}
return;
}
if (ch == '}') {
token = JSONToken.RBRACE;
next();
// next();
{
int index = ++bp;
if (index >= len) {
ch = EOI;
} else {
ch = text.charAt(index);
}
}
return;
}
if (ch == ']') {
token = JSONToken.RBRACKET;
next();
// next();
{
int index = ++bp;
if (index >= len) {
ch = EOI;
} else {
ch = text.charAt(index);
}
}
return;
}
@@ -397,7 +461,15 @@ public final class JSONLexer {
if (ch == '{') {
token = JSONToken.LBRACE;
next();
// next();
{
int index = ++bp;
if (index >= len) {
ch = EOI;
} else {
ch = text.charAt(index);
}
}
return;
}
break;
@@ -560,9 +632,8 @@ public final class JSONLexer {
public final String scanSymbol(final SymbolTable symbolTable) {
for (;;) {
if (ch < whitespaceFlags.length && whitespaceFlags[ch]) {
if (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t' || ch == '\f' || ch == '\b') {
next();
continue;
} else {
break;
}
@@ -612,7 +683,15 @@ public final class JSONLexer {
boolean hasSpecial = false;
char chLocal;
for (;;) {
chLocal = next();
// chLocal = next();
{
int index = ++bp;
if (index >= len) {
chLocal = ch = EOI;
} else {
chLocal = ch = text.charAt(index);
}
}
if (chLocal == quote) {
break;
@@ -772,7 +851,15 @@ public final class JSONLexer {
}
sp = 0;
this.next();
// this.next();
{
int index = ++bp;
if (index >= len) {
ch = EOI;
} else {
ch = text.charAt(index);
}
}
return value;
}
@@ -829,7 +916,15 @@ public final class JSONLexer {
hasSpecial = false;
char ch;
for (;;) {
ch = next();
// ch = next();
{
int index = ++bp;
if (index >= len) {
ch = this.ch = EOI;
} else {
ch = this.ch = text.charAt(index);
}
}
if (ch == '\"') {
break;
@@ -856,7 +951,15 @@ public final class JSONLexer {
text.getChars(np + 1, np + 1 + sp, sbuf, 0);
}
ch = next();
//ch = next();
{
int index = ++bp;
if (index >= this.len) {
ch = this.ch = EOI;
} else {
ch = this.ch = this.text.charAt(index);
}
}
switch (ch) {
case '0':
@@ -950,7 +1053,15 @@ public final class JSONLexer {
}
token = JSONToken.LITERAL_STRING;
this.ch = next();
// this.ch = next();
{
int index = ++bp;
if (index >= len) {
this.ch = EOI;
} else {
this.ch = text.charAt(index);
}
}
}
public Calendar getCalendar() {
@@ -1506,9 +1617,8 @@ public final class JSONLexer {
public final void skipWhitespace() {
for (;;) {
if (ch < whitespaceFlags.length && whitespaceFlags[ch]) {
if (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t' || ch == '\f' || ch == '\b') {
next();
continue;
} else {
break;
}
@@ -1689,7 +1799,15 @@ public final class JSONLexer {
} else {
break;
}
next();
// next();
{
int index = ++bp;
if (index >= len) {
this.ch = EOI;
} else {
this.ch = text.charAt(index);
}
}
}
boolean isDouble = false;
@@ -1837,16 +1955,6 @@ public final class JSONLexer {
return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t' || ch == '\f' || ch == '\b';
}
protected static boolean[] whitespaceFlags = new boolean[256];
static {
whitespaceFlags[' '] = true;
whitespaceFlags['\n'] = true;
whitespaceFlags['\r'] = true;
whitespaceFlags['\t'] = true;
whitespaceFlags['\f'] = true;
whitespaceFlags['\b'] = true;
}
protected static final long MULTMIN_RADIX_TEN = Long.MIN_VALUE / 10;
protected static final long N_MULTMAX_RADIX_TEN = -Long.MAX_VALUE / 10;
@@ -1878,10 +1986,24 @@ public final class JSONLexer {
ch = charAt(bp);
if (ch == '{') {
next();
{
int index = ++bp;
if (index >= len) {
ch = EOI;
} else {
ch = text.charAt(index);
}
}
token = JSONToken.LBRACE;
} else if (ch == '[') {
next();
{
int index = ++bp;
if (index >= len) {
ch = EOI;
} else {
ch = text.charAt(index);
}
}
token = JSONToken.LBRACKET;
} else {
nextToken();
@@ -1941,7 +2063,15 @@ public final class JSONLexer {
if (chLocal == ',') {
bp += (offset - 1);
this.next();
// this.next();
{
int index = ++bp;
if (index >= this.len) {
this.ch = EOI;
} else {
this.ch = this.text.charAt(index);
}
}
matchStat = VALUE;
token = JSONToken.COMMA;
return value;
@@ -1952,15 +2082,39 @@ public final class JSONLexer {
if (chLocal == ',') {
token = JSONToken.COMMA;
bp += (offset - 1);
this.next();
// this.next();
{
int index = ++bp;
if (index >= this.len) {
this.ch = EOI;
} else {
this.ch = this.text.charAt(index);
}
}
} else if (chLocal == ']') {
token = JSONToken.RBRACKET;
bp += (offset - 1);
this.next();
// this.next();
{
int index = ++bp;
if (index >= this.len) {
this.ch = EOI;
} else {
this.ch = this.text.charAt(index);
}
}
} else if (chLocal == '}') {
token = JSONToken.RBRACE;
bp += (offset - 1);
this.next();
// this.next();
{
int index = ++bp;
if (index >= this.len) {
this.ch = EOI;
} else {
this.ch = this.text.charAt(index);
}
}
} else if (chLocal == EOI) {
token = JSONToken.EOF;
bp += (offset - 1);
@@ -2014,7 +2168,15 @@ public final class JSONLexer {
if (chLocal == ',') {
bp += (offset - 1);
this.next();
// this.next();
{
int index = ++bp;
if (index >= this.len) {
this.ch = EOI;
} else {
this.ch = this.text.charAt(index);
}
}
matchStat = VALUE;
token = JSONToken.COMMA;
return value;
@@ -2025,15 +2187,39 @@ public final class JSONLexer {
if (chLocal == ',') {
token = JSONToken.COMMA;
bp += (offset - 1);
this.next();
// this.next();
{
int index = ++bp;
if (index >= this.len) {
this.ch = EOI;
} else {
this.ch = this.text.charAt(index);
}
}
} else if (chLocal == ']') {
token = JSONToken.RBRACKET;
bp += (offset - 1);
this.next();
// this.next();
{
int index = ++bp;
if (index >= this.len) {
this.ch = EOI;
} else {
this.ch = this.text.charAt(index);
}
}
} else if (chLocal == '}') {
token = JSONToken.RBRACE;
bp += (offset - 1);
this.next();
// this.next();
{
int index = ++bp;
if (index >= this.len) {
this.ch = EOI;
} else {
this.ch = this.text.charAt(index);
}
}
} else if (chLocal == EOI) {
token = JSONToken.EOF;
bp += (offset - 1);
@@ -2101,7 +2287,15 @@ public final class JSONLexer {
if (chLocal == ',') {
bp += (offset - 1);
this.next();
// this.next();
{
int index = ++bp;
if (index >= this.len) {
this.ch = EOI;
} else {
this.ch = this.text.charAt(index);
}
}
matchStat = VALUE;
return strVal;
}
@@ -2191,7 +2385,15 @@ public final class JSONLexer {
chLocal = charAt(bp + offset++);
if (chLocal == ',') {
bp += (offset - 1);
this.next();
// this.next();
{
int index = ++bp;
if (index >= this.len) {
this.ch = EOI;
} else {
this.ch = this.text.charAt(index);
}
}
matchStat = VALUE;
token = JSONToken.COMMA;
@@ -2203,15 +2405,39 @@ public final class JSONLexer {
if (chLocal == ',') {
token = JSONToken.COMMA;
bp += (offset - 1);
this.next();
// this.next();
{
int index = ++bp;
if (index >= this.len) {
this.ch = EOI;
} else {
this.ch = this.text.charAt(index);
}
}
} else if (chLocal == ']') {
token = JSONToken.RBRACKET;
bp += (offset - 1);
this.next();
// this.next();
{
int index = ++bp;
if (index >= this.len) {
this.ch = EOI;
} else {
this.ch = this.text.charAt(index);
}
}
} else if (chLocal == '}') {
token = JSONToken.RBRACE;
bp += (offset - 1);
this.next();
// this.next();
{
int index = ++bp;
if (index >= this.len) {
this.ch = EOI;
} else {
this.ch = this.text.charAt(index);
}
}
} else if (chLocal == EOI) {
token = JSONToken.EOF;
bp += (offset - 1);
@@ -2456,7 +2682,15 @@ public final class JSONLexer {
if (chLocal == ',') {
bp += (offset - 1);
this.next();
// this.next();
{
int index = ++bp;
if (index >= this.len) {
this.ch = EOI;
} else {
this.ch = this.text.charAt(index);
}
}
matchStat = VALUE;
return strVal;
}
@@ -11,6 +11,7 @@ public class OneFieldTest extends TestCase {
vo.setId(1001);
String text = JSON.toJSONString(vo);
System.out.println(text);
JSON.parseObject(text, VO.class);
}
@@ -10,7 +10,7 @@ public class BenchmarkMain {
BenchmarkExecutor executor = new BenchmarkExecutor();
executor.setExecuteCount(3);
executor.getCodecList().add(new FastjsonSCodec());
executor.getCodecList().add(new FastjsonCodec());
// executor.getCodecList().add(new FastjsonBeanToArrayCodec());
// executor.getCodecList().add(new GsonCodec());
// executor.getCodecList().add(new Jackson2Codec());
@@ -21,9 +21,9 @@ public class BenchmarkMain {
executor.setLoopCount(1000 * 1);
// executor.getCaseList().add(new EishayDecodeBytes());
// executor.getCaseList().add(new TradeObjectParse());
// executor.getCaseList().add(new EishayDecode2Bytes());
executor.getCaseList().add(new EishayEncode());
executor.getCaseList().add(new EishayDecode());
// executor.getCaseList().add(new EishayDecodeByClassName());
// executor.getCaseList().add(new EishayTreeDecode());
// executor.getCaseList().add(new Eishay3Encode());
@@ -0,0 +1,47 @@
package com.alibaba.json.test.benchmark.decode;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import com.alibaba.json.test.benchmark.BenchmarkCase;
import com.alibaba.json.test.codec.Codec;
/**
* Created by wenshao on 16/4/4.
*/
public class TradeObjectParse extends BenchmarkCase {
private String text;
public TradeObjectParse(){
super("TradeObjectParse");
// JavaBeanMapping.getGlobalInstance().putDeserializer(Image.class, new ImageDeserializer());
// JavaBeanMapping.getGlobalInstance().putDeserializer(Media.class, new MediaDeserializer());
}
public void init(Codec codec) throws Exception {
InputStream is = TradeObjectParse.class.getClassLoader().getResourceAsStream("json/trade.json");
Reader reader = new InputStreamReader(is, "UTF-8");
char[] chars = new char[1024];
StringBuilder out = new StringBuilder();
for (;;) {
int len = reader.read(chars);
if (len <= 0) {
break;
}
out.append(chars, 0, len);
}
reader.close();
text = out.toString();
System.out.println("tradeJsonObject " + text.substring(100));
}
@Override
public void execute(Codec codec) throws Exception {
codec.decode(text);
}
}
File diff suppressed because one or more lines are too long