Skip to content

Commit

Permalink
improve performance for android
Browse files Browse the repository at this point in the history
  • Loading branch information
wenshao committed Jan 27, 2024
1 parent 4cafb9a commit 5960261
Show file tree
Hide file tree
Showing 3 changed files with 206 additions and 100 deletions.
59 changes: 32 additions & 27 deletions core/src/main/java/com/alibaba/fastjson2/JSONReaderASCII.java
Original file line number Diff line number Diff line change
Expand Up @@ -976,19 +976,20 @@ public final long getNameHashCodeLCase() {

@Override
public final String getFieldName() {
int length = nameEnd - nameBegin;
int offset = nameBegin;
int length = nameEnd - offset;
if (!nameEscape) {
if (this.str != null) {
return this.str.substring(nameBegin, nameEnd);
return this.str.substring(offset, nameEnd);
} else if (ANDROID) {
return getLatin1String(offset, length);
} else {
return new String(bytes, nameBegin, length, StandardCharsets.ISO_8859_1);
return new String(bytes, offset, length, StandardCharsets.ISO_8859_1);
}
}

if (JDKUtils.STRING_CREATOR_JDK11 != null) {
byte[] chars = new byte[nameLength];

int offset = nameBegin;
forStmt:
for (int i = 0; offset < nameEnd; ++i) {
byte b = bytes[offset];
Expand All @@ -997,11 +998,12 @@ public final String getFieldName() {
b = bytes[++offset];
switch (b) {
case 'u': {
int c1 = bytes[++offset];
int c2 = bytes[++offset];
int c3 = bytes[++offset];
int c4 = bytes[++offset];
int c1 = bytes[offset + 1];
int c2 = bytes[offset + 2];
int c3 = bytes[offset + 3];
int c4 = bytes[offset + 4];
char c = char4(c1, c2, c3, c4);
offset += 4;
if (c > 0xFF) {
chars = null;
break forStmt;
Expand All @@ -1010,8 +1012,9 @@ public final String getFieldName() {
break;
}
case 'x': {
int c1 = bytes[++offset];
int c2 = bytes[++offset];
int c1 = bytes[offset + 1];
int c2 = bytes[offset + 2];
offset += 2;
char c = char2(c1, c2);
if (c > 0xFF) {
chars = null;
Expand Down Expand Up @@ -1050,26 +1053,26 @@ public final String getFieldName() {
}

char[] chars = new char[nameLength];

int offset = nameBegin;
for (int i = 0; offset < nameEnd; ++i) {
char c = (char) (bytes[offset] & 0xff);

if (c == '\\') {
c = (char) bytes[++offset];
switch (c) {
case 'u': {
int c1 = bytes[++offset];
int c2 = bytes[++offset];
int c3 = bytes[++offset];
int c4 = bytes[++offset];
int c1 = bytes[offset + 1];
int c2 = bytes[offset + 2];
int c3 = bytes[offset + 3];
int c4 = bytes[offset + 4];
c = char4(c1, c2, c3, c4);
offset += 4;
break;
}
case 'x': {
int c1 = bytes[++offset];
int c2 = bytes[++offset];
int c1 = bytes[offset + 1];
int c2 = bytes[offset + 2];
c = char2(c1, c2);
offset += 2;
break;
}
case '.':
Expand Down Expand Up @@ -1612,17 +1615,17 @@ public String readString() {
c = (char) bytes[++offset];
switch (c) {
case 'u': {
char c1 = (char) this.bytes[++offset];
char c2 = (char) this.bytes[++offset];
char c3 = (char) this.bytes[++offset];
char c4 = (char) this.bytes[++offset];
c = char4(c1, c2, c3, c4);
c = char4(
(char) this.bytes[offset + 1],
(char) this.bytes[offset + 2],
(char) this.bytes[offset + 3],
(char) this.bytes[offset + 4]);
offset += 4;
break;
}
case 'x': {
char c1 = (char) this.bytes[++offset];
char c2 = (char) this.bytes[++offset];
c = char2(c1, c2);
c = char2((char) this.bytes[offset + 1], (char) this.bytes[offset + 2]);
offset += 2;
break;
}
case '\\':
Expand Down Expand Up @@ -1661,6 +1664,8 @@ public String readString() {
} else if (STRING_CREATOR_JDK11 != null) {
byte[] bytes = Arrays.copyOfRange(this.bytes, this.offset, offset);
str = STRING_CREATOR_JDK11.apply(bytes, LATIN1);
} else if (ANDROID) {
str = getLatin1String(this.offset, offset - this.offset);
} else {
str = new String(bytes, this.offset, offset - this.offset, StandardCharsets.ISO_8859_1);
}
Expand Down
101 changes: 72 additions & 29 deletions core/src/main/java/com/alibaba/fastjson2/JSONReaderJSONB.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import static com.alibaba.fastjson2.util.DateUtils.*;
import static com.alibaba.fastjson2.util.JDKUtils.*;
import static com.alibaba.fastjson2.util.TypeUtils.toBigDecimal;
import static java.nio.charset.StandardCharsets.ISO_8859_1;

final class JSONReaderJSONB
extends JSONReader {
Expand All @@ -37,6 +38,7 @@ final class JSONReaderJSONB
protected int strBegin;

protected byte[] valueBytes;
protected char[] charBuf;
protected final CacheItem cacheItem;

protected final SymbolTable symbolTable;
Expand Down Expand Up @@ -105,7 +107,7 @@ public String getString() {

Charset charset;
if (strtype == BC_STR_ASCII) {
charset = StandardCharsets.ISO_8859_1;
charset = ISO_8859_1;
} else if (strtype >= BC_STR_ASCII_FIX_MIN && strtype <= BC_STR_ASCII_FIX_MAX) {
if (STRING_CREATOR_JDK8 != null) {
char[] chars = new char[strlen];
Expand All @@ -118,7 +120,7 @@ public String getString() {
System.arraycopy(bytes, strBegin, chars, 0, strlen);
return STRING_CREATOR_JDK11.apply(chars, LATIN1);
}
charset = StandardCharsets.ISO_8859_1;
charset = ISO_8859_1;
} else if (strtype == BC_STR_UTF8) {
charset = StandardCharsets.UTF_8;
} else if (strtype == BC_STR_UTF16) {
Expand Down Expand Up @@ -965,7 +967,10 @@ public Object readAny() {
}
return str;
}
String str = new String(bytes, offset, strlen, StandardCharsets.ISO_8859_1);

String str = ANDROID
? getLatin1String(offset, strlen)
: new String(bytes, offset, strlen, ISO_8859_1);
offset += strlen;

if ((context.features & Feature.TrimString.mask) != 0) {
Expand Down Expand Up @@ -2496,6 +2501,24 @@ public boolean skipName() {
throw new JSONException("name not support input : " + typeName(strtype));
}

final String getLatin1String(int offset, int length) {
if (JDKUtils.ANDROID_SDK_INT >= 34) {
return new String(bytes, offset, length, ISO_8859_1);
}

char[] charBuf = this.charBuf;
if (charBuf == null) {
this.charBuf = charBuf = CHARS_UPDATER.getAndSet(cacheItem, null);
}
if (charBuf == null || charBuf.length < length) {
this.charBuf = charBuf = new char[length];
}
for (int i = 0; i < length; i++) {
charBuf[i] = (char) (bytes[offset + i] & 0xFF);
}
return new String(charBuf, 0, length);
}

@Override
public String readFieldName() {
strtype = bytes[offset];
Expand Down Expand Up @@ -2652,7 +2675,7 @@ public String readFieldName() {
}
name = STRING_CREATOR_JDK8.apply(chars, Boolean.TRUE);
} else {
name = new String(bytes, offset, strlen, StandardCharsets.ISO_8859_1);
name = new String(bytes, offset, strlen, ISO_8859_1);
}

NAME_CACHE2[indexMask] = new JSONFactory.NameCacheEntry2(name, nameValue0, nameValue1);
Expand All @@ -2674,7 +2697,7 @@ public String readFieldName() {
}
name = STRING_CREATOR_JDK8.apply(chars, Boolean.TRUE);
} else {
name = new String(bytes, offset, strlen, StandardCharsets.ISO_8859_1);
name = new String(bytes, offset, strlen, ISO_8859_1);
}

NAME_CACHE[indexMask] = new JSONFactory.NameCacheEntry(name, nameValue0);
Expand All @@ -2688,20 +2711,25 @@ public String readFieldName() {
}

if (str == null) {
if (STRING_CREATOR_JDK8 != null && strlen >= 0) {
char[] chars = new char[strlen];
for (int i = 0; i < strlen; ++i) {
chars[i] = (char) (bytes[offset + i] & 0xff);
if (strlen >= 0) {
if (STRING_CREATOR_JDK8 != null) {
char[] chars = new char[strlen];
for (int i = 0; i < strlen; ++i) {
chars[i] = (char) (bytes[offset + i] & 0xff);
}
offset += strlen;
str = STRING_CREATOR_JDK8.apply(chars, Boolean.TRUE);
} else if (ANDROID) {
str = getLatin1String(offset, strlen);
offset += strlen;
} else if (STRING_CREATOR_JDK11 != null) {
byte[] chars = new byte[strlen];
System.arraycopy(bytes, offset, chars, 0, strlen);
str = STRING_CREATOR_JDK11.apply(chars, LATIN1);
offset += strlen;
}
offset += strlen;
str = STRING_CREATOR_JDK8.apply(chars, Boolean.TRUE);
} else if (STRING_CREATOR_JDK11 != null && strlen >= 0) {
byte[] chars = new byte[strlen];
System.arraycopy(bytes, offset, chars, 0, strlen);
str = STRING_CREATOR_JDK11.apply(chars, LATIN1);
offset += strlen;
}
charset = StandardCharsets.ISO_8859_1;
charset = ISO_8859_1;
}
} else if (strtype == BC_STR_UTF8) {
strlen = readLength();
Expand Down Expand Up @@ -2772,7 +2800,11 @@ public String readFieldName() {
}

if (str == null) {
str = new String(bytes, offset, strlen, charset);
if (charset == ISO_8859_1 && ANDROID) {
str = getLatin1String(offset, strlen);
} else {
str = new String(bytes, offset, strlen, charset);
}
offset += strlen;
}

Expand Down Expand Up @@ -2806,6 +2838,7 @@ public String getFieldName() {

@Override
public String readString() {
byte[] bytes = this.bytes;
final byte strtype = bytes[offset++];
this.strtype = strtype;
if (strtype == BC_NULL) {
Expand Down Expand Up @@ -2840,6 +2873,9 @@ public String readString() {
}
offset += strlen;
str = STRING_CREATOR_JDK8.apply(chars, Boolean.TRUE);
} else if (ANDROID) {
str = getLatin1String(offset, strlen);
offset += strlen;
} else if (STRING_CREATOR_JDK11 != null) {
byte[] chars = new byte[strlen];
System.arraycopy(bytes, offset, chars, 0, strlen);
Expand All @@ -2862,7 +2898,7 @@ public String readString() {
private String readStringNonAscii(String str, boolean ascii) {
Charset charset;
if (ascii) {
charset = StandardCharsets.ISO_8859_1;
charset = ISO_8859_1;
} else if (strtype == BC_STR_UTF8) {
str = readStringUTF8();
charset = StandardCharsets.UTF_8;
Expand Down Expand Up @@ -3361,7 +3397,7 @@ private long readInt64Value0(byte[] bytes, byte type) {
}
case BC_STR_ASCII: {
int strlen = readInt32Value();
String str = new String(bytes, offset, strlen, StandardCharsets.ISO_8859_1);
String str = new String(bytes, offset, strlen, ISO_8859_1);
offset += strlen;
if (str.indexOf('.') == -1) {
return new BigInteger(str).intValue();
Expand Down Expand Up @@ -3503,7 +3539,7 @@ private int readInt32Value0(byte[] bytes, byte type) {
return int32Value;
case BC_STR_ASCII: {
int strlen = readInt32Value();
String str = new String(bytes, offset, strlen, StandardCharsets.ISO_8859_1);
String str = new String(bytes, offset, strlen, ISO_8859_1);
offset += strlen;
if (str.indexOf('.') == -1) {
return new BigInteger(str).intValue();
Expand Down Expand Up @@ -3650,8 +3686,10 @@ protected String readFixedAsciiString(int strlen) {
}

str = STRING_CREATOR_JDK8.apply(chars, Boolean.TRUE);
} else if (ANDROID) {
str = getLatin1String(offset, strlen);
} else {
str = new String(bytes, offset, strlen, StandardCharsets.ISO_8859_1);
str = new String(bytes, offset, strlen, ISO_8859_1);
}
return str;
}
Expand Down Expand Up @@ -3729,7 +3767,7 @@ private float readFloat0() {
}
case BC_STR_ASCII: {
int strlen = readInt32Value();
String str = new String(bytes, offset, strlen, StandardCharsets.ISO_8859_1);
String str = new String(bytes, offset, strlen, ISO_8859_1);
offset += strlen;
if (str.indexOf('.') == -1) {
return new BigInteger(str).intValue();
Expand Down Expand Up @@ -3881,7 +3919,7 @@ private double readDoubleValue0() {
return readInt64Value();
case BC_STR_ASCII: {
int strlen = readInt32Value();
String str = new String(bytes, offset, strlen, StandardCharsets.ISO_8859_1);
String str = new String(bytes, offset, strlen, ISO_8859_1);
offset += strlen;
if (str.indexOf('.') == -1) {
return new BigInteger(str).intValue();
Expand Down Expand Up @@ -4087,7 +4125,7 @@ public Number readNumber() {
}
case BC_STR_ASCII: {
int strlen = readInt32Value();
String str = new String(bytes, offset, strlen, StandardCharsets.ISO_8859_1);
String str = new String(bytes, offset, strlen, ISO_8859_1);
offset += strlen;
return toBigDecimal(str);
}
Expand Down Expand Up @@ -4206,7 +4244,7 @@ private BigDecimal readDecimal0(byte type) {
}
case BC_STR_ASCII: {
int strlen = readInt32Value();
String str = new String(bytes, offset, strlen, StandardCharsets.ISO_8859_1);
String str = new String(bytes, offset, strlen, ISO_8859_1);
offset += strlen;
return toBigDecimal(str);
}
Expand Down Expand Up @@ -4360,7 +4398,7 @@ private BigInteger readBigInteger0(byte type) {
}
case BC_STR_ASCII: {
int strlen = readInt32Value();
String str = new String(bytes, offset, strlen, StandardCharsets.ISO_8859_1);
String str = new String(bytes, offset, strlen, ISO_8859_1);
offset += strlen;
if (str.indexOf('.') == -1) {
return new BigInteger(str);
Expand Down Expand Up @@ -4918,7 +4956,7 @@ public UUID readUUID() {
offset += 36;
return new UUID(hi, lo);
}
throw new JSONException("Invalid UUID string: " + new String(bytes, offset, 36, StandardCharsets.ISO_8859_1));
throw new JSONException("Invalid UUID string: " + new String(bytes, offset, 36, ISO_8859_1));
}
case BC_STR_ASCII:
case BC_STR_UTF8: {
Expand Down Expand Up @@ -5095,7 +5133,7 @@ private boolean readBoolValue0(byte type) {
return false;
}
}
String str = new String(bytes, offset, strlen, StandardCharsets.ISO_8859_1);
String str = new String(bytes, offset, strlen, ISO_8859_1);
offset += strlen;
throw new JSONException("not support input " + str);
}
Expand Down Expand Up @@ -5402,6 +5440,11 @@ public void close() {
if (valueBytes != null && valueBytes.length < CACHE_THRESHOLD) {
BYTES_UPDATER.lazySet(cacheItem, valueBytes);
}

char[] nameChars = this.charBuf;
if (nameChars != null && nameChars.length < CACHE_THRESHOLD) {
CHARS_UPDATER.lazySet(cacheItem, nameChars);
}
}

public boolean isEnd() {
Expand Down
Loading

0 comments on commit 5960261

Please sign in to comment.