Skip to content

Commit

Permalink
improved float/double parse performance.
Browse files Browse the repository at this point in the history
  • Loading branch information
wenshao committed Aug 4, 2017
1 parent ef6c08a commit 599b313
Show file tree
Hide file tree
Showing 5 changed files with 228 additions and 96 deletions.
121 changes: 46 additions & 75 deletions src/main/java/com/alibaba/fastjson/parser/JSONLexerBase.java
Expand Up @@ -90,7 +90,7 @@ public JSONLexerBase(int features){
public final int matchStat() { public final int matchStat() {
return matchStat; return matchStat;
} }

/** /**
* internal method, don't invoke * internal method, don't invoke
* @param token * @param token
Expand Down Expand Up @@ -536,7 +536,7 @@ public final boolean isEnabled(Feature feature) {
public final boolean isEnabled(int feature) { public final boolean isEnabled(int feature) {
return (this.features & feature) != 0; return (this.features & feature) != 0;
} }

public final boolean isEnabled(int features, int feature) { public final boolean isEnabled(int features, int feature) {
return (this.features & feature) != 0 || (features & feature) != 0; return (this.features & feature) != 0 || (features & feature) != 0;
} }
Expand Down Expand Up @@ -828,7 +828,7 @@ public final String scanSymbolUnQuoted(final SymbolTable symbolTable) {
final boolean firstFlag = ch >= firstIdentifierFlags.length || firstIdentifierFlags[first]; final boolean firstFlag = ch >= firstIdentifierFlags.length || firstIdentifierFlags[first];
if (!firstFlag) { if (!firstFlag) {
throw new JSONException("illegal identifier : " + ch // throw new JSONException("illegal identifier : " + ch //
+ info()); + info());
} }


final boolean[] identifierFlags = IOUtils.identifierFlags; final boolean[] identifierFlags = IOUtils.identifierFlags;
Expand Down Expand Up @@ -858,7 +858,7 @@ public final String scanSymbolUnQuoted(final SymbolTable symbolTable) {


final int NULL_HASH = 3392903; final int NULL_HASH = 3392903;
if (sp == 4 && hash == NULL_HASH && charAt(np) == 'n' && charAt(np + 1) == 'u' && charAt(np + 2) == 'l' if (sp == 4 && hash == NULL_HASH && charAt(np) == 'n' && charAt(np + 1) == 'u' && charAt(np + 2) == 'l'
&& charAt(np + 3) == 'l') { && charAt(np + 3) == 'l') {
return null; return null;
} }


Expand Down Expand Up @@ -1097,9 +1097,9 @@ public final boolean isRef() {
return false; return false;
} }


return charAt(np + 1) == '$' // return charAt(np + 1) == '$' //
&& charAt(np + 2) == 'r' // && charAt(np + 2) == 'r' //
&& charAt(np + 3) == 'e' // && charAt(np + 3) == 'e' //
&& charAt(np + 4) == 'f'; && charAt(np + 4) == 'f';
} }


Expand Down Expand Up @@ -1508,18 +1508,18 @@ public String scanSymbolWithSeperator(final SymbolTable symbolTable, char serper
} }
} }
} }

public Collection<String> newCollectionByType(Class<?> type){ public Collection<String> newCollectionByType(Class<?> type){
if (type.isAssignableFrom(HashSet.class)) { if (type.isAssignableFrom(HashSet.class)) {
HashSet<String> list = new HashSet<String>(); HashSet<String> list = new HashSet<String>();
return list; return list;
} else if (type.isAssignableFrom(ArrayList.class)) { } else if (type.isAssignableFrom(ArrayList.class)) {
ArrayList<String> list2 = new ArrayList<String>(); ArrayList<String> list2 = new ArrayList<String>();
return list2; return list2;
} else { } else {
try { try {
Collection<String> list = (Collection<String>) type.newInstance(); Collection<String> list = (Collection<String>) type.newInstance();
return list; return list;
} catch (Exception e) { } catch (Exception e) {
throw new JSONException(e.getMessage(), e); throw new JSONException(e.getMessage(), e);
} }
Expand Down Expand Up @@ -1598,8 +1598,8 @@ public Collection<String> scanFieldStringArray(char[] fieldName, Class<?> type)
chLocal = charAt(bp + (offset++)); chLocal = charAt(bp + (offset++));


list.add(stringVal); list.add(stringVal);
} else if (chLocal == 'n' // } else if (chLocal == 'n' //
&& charAt(bp + offset) == 'u' // && charAt(bp + offset) == 'u' //
&& charAt(bp + offset + 1) == 'l' // && charAt(bp + offset + 1) == 'l' //
&& charAt(bp + offset + 2) == 'l') { && charAt(bp + offset + 2) == 'l') {
offset += 3; offset += 3;
Expand Down Expand Up @@ -1663,7 +1663,7 @@ && charAt(bp + offset + 2) == 'l') {


return list; return list;
} }

public void scanStringArray(Collection<String> list, char seperator) { public void scanStringArray(Collection<String> list, char seperator) {
matchStat = UNKNOWN; matchStat = UNKNOWN;


Expand Down Expand Up @@ -1691,9 +1691,9 @@ && charAt(bp + offset + 3) == seperator


for (;;) { for (;;) {
if (chLocal == 'n' // if (chLocal == 'n' //
&& charAt(bp + offset) == 'u' // && charAt(bp + offset) == 'u' //
&& charAt(bp + offset + 1) == 'l' // && charAt(bp + offset + 1) == 'l' //
&& charAt(bp + offset + 2) == 'l') { && charAt(bp + offset + 2) == 'l') {
offset += 3; offset += 3;
chLocal = charAt(bp + (offset++)); chLocal = charAt(bp + (offset++));
list.add(null); list.add(null);
Expand Down Expand Up @@ -1794,10 +1794,10 @@ public int scanFieldInt(char[] fieldName) {
} }
} }
if (value < 0 // if (value < 0 //
|| offset > 11 + 3 + fieldName.length) { || offset > 11 + 3 + fieldName.length) {
if (value != Integer.MIN_VALUE // if (value != Integer.MIN_VALUE //
|| offset != 17 // || offset != 17 //
|| !negative) { || !negative) {
matchStat = NOT_MATCH; matchStat = NOT_MATCH;
return 0; return 0;
} }
Expand Down Expand Up @@ -1962,8 +1962,8 @@ public boolean scanBoolean(char expectNext) {
boolean value = false; boolean value = false;
if (chLocal == 't') { if (chLocal == 't') {
if (charAt(bp + offset) == 'r' // if (charAt(bp + offset) == 'r' //
&& charAt(bp + offset + 1) == 'u' // && charAt(bp + offset + 1) == 'u' //
&& charAt(bp + offset + 2) == 'e') { && charAt(bp + offset + 2) == 'e') {
offset += 3; offset += 3;
chLocal = charAt(bp + (offset++)); chLocal = charAt(bp + (offset++));
value = true; value = true;
Expand All @@ -1973,9 +1973,9 @@ && charAt(bp + offset + 2) == 'e') {
} }
} else if (chLocal == 'f') { } else if (chLocal == 'f') {
if (charAt(bp + offset) == 'a' // if (charAt(bp + offset) == 'a' //
&& charAt(bp + offset + 1) == 'l' // && charAt(bp + offset + 1) == 'l' //
&& charAt(bp + offset + 2) == 's' // && charAt(bp + offset + 2) == 's' //
&& charAt(bp + offset + 3) == 'e') { && charAt(bp + offset + 3) == 'e') {
offset += 4; offset += 4;
chLocal = charAt(bp + (offset++)); chLocal = charAt(bp + (offset++));
value = false; value = false;
Expand Down Expand Up @@ -2324,7 +2324,7 @@ public final float scanFieldFloat(char[] fieldName) {
chLocal = charAt(bp + (offset++)); chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') { if (chLocal >= '0' && chLocal <= '9') {
intVal = intVal * 10 + (chLocal - '0'); intVal = intVal * 10 + (chLocal - '0');
power *= 10; power = 10;
for (;;) { for (;;) {
chLocal = charAt(bp + (offset++)); chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') { if (chLocal >= '0' && chLocal <= '9') {
Expand Down Expand Up @@ -2453,18 +2453,13 @@ public final float scanFloat(char seperator) {
} }
} }


int power = 1; if (chLocal == '.') {
boolean small = (chLocal == '.');
if (small) {
chLocal = charAt(bp + (offset++)); chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') { if (chLocal >= '0' && chLocal <= '9') {
intVal = intVal * 10 + (chLocal - '0');
power *= 10;
for (;;) { for (;;) {
chLocal = charAt(bp + (offset++)); chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') { if (chLocal >= '0' && chLocal <= '9') {
intVal = intVal * 10 + (chLocal - '0'); intVal = intVal * 10 + (chLocal - '0');
power *= 10;
continue; continue;
} else { } else {
break; break;
Expand All @@ -2476,22 +2471,6 @@ public final float scanFloat(char seperator) {
} }
} }


boolean exp = chLocal == 'e' || chLocal == 'E';
if (exp) {
chLocal = charAt(bp + (offset++));
if (chLocal == '+' || chLocal == '-') {
chLocal = charAt(bp + (offset++));
}
for (;;) {
if (chLocal >= '0' && chLocal <= '9') {
chLocal = charAt(bp + (offset++));
} else {
break;
}
}
}


int start, count; int start, count;
if (quote) { if (quote) {
if (chLocal != '"') { if (chLocal != '"') {
Expand All @@ -2506,16 +2485,8 @@ public final float scanFloat(char seperator) {
start = bp; start = bp;
count = bp + offset - start - 1; count = bp + offset - start - 1;
} }

String text = this.subString(start, count);
if (!exp && count < 20) { value = Float.parseFloat(text);
value = ((float) intVal) / power;
if (negative) {
value = -value;
}
} else {
String text = this.subString(start, count);
value = Float.parseFloat(text);
}
} else { } else {
matchStat = NOT_MATCH; matchStat = NOT_MATCH;
return 0; return 0;
Expand All @@ -2533,7 +2504,7 @@ public final float scanFloat(char seperator) {
} }
} }


public final double scanDouble(char seperator) { public double scanDouble(char seperator) {
matchStat = UNKNOWN; matchStat = UNKNOWN;


int offset = 0; int offset = 0;
Expand Down Expand Up @@ -2567,7 +2538,7 @@ public final double scanDouble(char seperator) {
chLocal = charAt(bp + (offset++)); chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') { if (chLocal >= '0' && chLocal <= '9') {
intVal = intVal * 10 + (chLocal - '0'); intVal = intVal * 10 + (chLocal - '0');
power *= 10; power = 10;
for (;;) { for (;;) {
chLocal = charAt(bp + (offset++)); chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') { if (chLocal >= '0' && chLocal <= '9') {
Expand Down Expand Up @@ -2683,7 +2654,7 @@ public final float[] scanFieldFloatArray(char[] fieldName) {
boolean small = (chLocal == '.'); boolean small = (chLocal == '.');
if (small) { if (small) {
chLocal = charAt(bp + (offset++)); chLocal = charAt(bp + (offset++));
power *= 10; power = 10;
if (chLocal >= '0' && chLocal <= '9') { if (chLocal >= '0' && chLocal <= '9') {
intVal = intVal * 10 + (chLocal - '0'); intVal = intVal * 10 + (chLocal - '0');
for (; ; ) { for (; ; ) {
Expand Down Expand Up @@ -2849,7 +2820,7 @@ public final float[][] scanFieldFloatArray2(char[] fieldName) {


if (chLocal >= '0' && chLocal <= '9') { if (chLocal >= '0' && chLocal <= '9') {
intVal = intVal * 10 + (chLocal - '0'); intVal = intVal * 10 + (chLocal - '0');
power *= 10; power = 10;
for (; ; ) { for (; ; ) {
chLocal = charAt(bp + (offset++)); chLocal = charAt(bp + (offset++));


Expand Down Expand Up @@ -3022,7 +2993,7 @@ public final double scanFieldDouble(char[] fieldName) {
chLocal = charAt(bp + (offset++)); chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') { if (chLocal >= '0' && chLocal <= '9') {
intVal = intVal * 10 + (chLocal - '0'); intVal = intVal * 10 + (chLocal - '0');
power *= 10; power = 10;
for (;;) { for (;;) {
chLocal = charAt(bp + (offset++)); chLocal = charAt(bp + (offset++));
if (chLocal >= '0' && chLocal <= '9') { if (chLocal >= '0' && chLocal <= '9') {
Expand Down Expand Up @@ -3144,7 +3115,7 @@ public final void scanTrue() {
next(); next();


if (ch == ' ' || ch == ',' || ch == '}' || ch == ']' || ch == '\n' || ch == '\r' || ch == '\t' || ch == EOI if (ch == ' ' || ch == ',' || ch == '}' || ch == ']' || ch == '\n' || ch == '\r' || ch == '\t' || ch == EOI
|| ch == '\f' || ch == '\b' || ch == ':' || ch == '/') { || ch == '\f' || ch == '\b' || ch == ':' || ch == '/') {
token = JSONToken.TRUE; token = JSONToken.TRUE;
} else { } else {
throw new JSONException("scan true error"); throw new JSONException("scan true error");
Expand All @@ -3170,7 +3141,7 @@ public final void scanNullOrNew() {
next(); next();


if (ch == ' ' || ch == ',' || ch == '}' || ch == ']' || ch == '\n' || ch == '\r' || ch == '\t' || ch == EOI if (ch == ' ' || ch == ',' || ch == '}' || ch == ']' || ch == '\n' || ch == '\r' || ch == '\t' || ch == EOI
|| ch == '\f' || ch == '\b') { || ch == '\f' || ch == '\b') {
token = JSONToken.NULL; token = JSONToken.NULL;
} else { } else {
throw new JSONException("scan null error"); throw new JSONException("scan null error");
Expand All @@ -3189,7 +3160,7 @@ public final void scanNullOrNew() {
next(); next();


if (ch == ' ' || ch == ',' || ch == '}' || ch == ']' || ch == '\n' || ch == '\r' || ch == '\t' || ch == EOI if (ch == ' ' || ch == ',' || ch == '}' || ch == ']' || ch == '\n' || ch == '\r' || ch == '\t' || ch == EOI
|| ch == '\f' || ch == '\b') { || ch == '\f' || ch == '\b') {
token = JSONToken.NEW; token = JSONToken.NEW;
} else { } else {
throw new JSONException("scan new error"); throw new JSONException("scan new error");
Expand Down Expand Up @@ -3223,7 +3194,7 @@ public final void scanFalse() {
next(); next();


if (ch == ' ' || ch == ',' || ch == '}' || ch == ']' || ch == '\n' || ch == '\r' || ch == '\t' || ch == EOI if (ch == ' ' || ch == ',' || ch == '}' || ch == ']' || ch == '\n' || ch == '\r' || ch == '\t' || ch == EOI
|| ch == '\f' || ch == '\b' || ch == ':' || ch == '/') { || ch == '\f' || ch == '\b' || ch == ':' || ch == '/') {
token = JSONToken.FALSE; token = JSONToken.FALSE;
} else { } else {
throw new JSONException("scan false error"); throw new JSONException("scan false error");
Expand Down Expand Up @@ -3344,10 +3315,10 @@ public static String readString(char[] chars, int chars_len) {
break; break;
case 'u': case 'u':
sbuf[len++] = (char) Integer.parseInt(new String(new char[] { chars[++i], // sbuf[len++] = (char) Integer.parseInt(new String(new char[] { chars[++i], //
chars[++i], // chars[++i], //
chars[++i], // chars[++i], //
chars[++i] }), chars[++i] }),
16); 16);
break; break;
default: default:
throw new JSONException("unclosed.str.lit"); throw new JSONException("unclosed.str.lit");
Expand Down

0 comments on commit 599b313

Please sign in to comment.