Compare commits

...

1 Commits

Author SHA1 Message Date
shaojin.wensj
c8987d32d6 unsafe write chunk optimization 2023-08-03 23:43:45 +08:00
20 changed files with 1034 additions and 936 deletions

View File

@ -13,6 +13,9 @@ import org.openjdk.jmh.runner.options.OptionsBuilder;
import java.io.InputStream;
import java.util.concurrent.TimeUnit;
import static com.alibaba.fastjson2.util.JDKUtils.ARRAY_BYTE_BASE_OFFSET;
import static com.alibaba.fastjson2.util.JDKUtils.UNSAFE;
public class BytesAsciiCheck {
static byte[] bytes;
@ -50,6 +53,11 @@ public class BytesAsciiCheck {
bh.consume(hasNegatives_8(bytes, 0, bytes.length));
}
@Benchmark
public void direct8u(Blackhole bh) throws Throwable {
bh.consume(hasNegatives_8u(bytes, 0, bytes.length));
}
public static boolean hasNegatives(byte[] ba, int off, int len) {
for (int i = off; i < off + len; i++) {
if (ba[i] < 0) {
@ -84,6 +92,23 @@ public class BytesAsciiCheck {
return false;
}
public static boolean hasNegatives_8u(byte[] bytes, int off, int len) {
int i = off;
while (i + 8 <= off + len) {
if ((UNSAFE.getLong(bytes, ARRAY_BYTE_BASE_OFFSET + off) & 0x8080808080808080L) != 0) {
return true;
}
i += 8;
}
for (; i < off + len; i++) {
if (bytes[i] < 0) {
return true;
}
}
return false;
}
public static void main(String[] args) throws Exception {
Options options = new OptionsBuilder()
.include(BytesAsciiCheck.class.getName())

View File

@ -2,6 +2,7 @@ package com.alibaba.fastjson2.benchmark.primitves;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONB;
import com.alibaba.fastjson2.JSONWriter;
import com.alibaba.fastjson2.benchmark.primitves.vo.BigDecimal20Field;
import com.caucho.hessian.io.Hessian2Input;
import com.caucho.hessian.io.Hessian2Output;
@ -27,6 +28,7 @@ import java.util.concurrent.TimeUnit;
public class BigDecimal20 {
static String str;
static BigDecimal20Field bean;
static byte[] jsonbBytes;
static ObjectMapper mapper = new ObjectMapper();
static Gson gson = new Gson();
@ -47,7 +49,7 @@ public class BigDecimal20 {
try {
InputStream is = BigDecimal20.class.getClassLoader().getResourceAsStream("data/dec20.json");
str = IOUtils.toString(is, "UTF-8");
BigDecimal20Field bean = JSON.parseObject(str, BigDecimal20Field.class);
bean = JSON.parseObject(str, BigDecimal20Field.class);
jsonbBytes = JSONB.toBytes(bean);
kryo = new Kryo();
@ -86,6 +88,12 @@ public class BigDecimal20 {
);
}
public void fastjson2_ser(Blackhole bh) {
bh.consume(
JSON.toJSONBytes(bean, JSONWriter.Feature.BeanToArray)
);
}
@Benchmark
public void jsonb(Blackhole bh) {
bh.consume(

View File

@ -2,6 +2,7 @@ package com.alibaba.fastjson2.benchmark.primitves;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONB;
import com.alibaba.fastjson2.JSONWriter;
import com.alibaba.fastjson2.benchmark.primitves.vo.Int20Field;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.io.IOUtils;
@ -20,6 +21,7 @@ public class IntValue20 {
static final Class OBJECT_CLASS = Int20Field.class;
static String str;
static byte[] jsonbBytes;
static Object object;
static ObjectMapper mapper = new ObjectMapper();
public IntValue20() {
@ -29,6 +31,7 @@ public class IntValue20 {
jsonbBytes = JSONB.toBytes(
JSON.parseObject(str, OBJECT_CLASS)
);
object = JSON.parseObject(str, OBJECT_CLASS);
} catch (Exception ex) {
ex.printStackTrace();
}
@ -55,6 +58,12 @@ public class IntValue20 {
);
}
public void fastjson2_ser(Blackhole bh) {
bh.consume(
JSON.toJSONBytes(object, JSONWriter.Feature.BeanToArray)
);
}
@Benchmark
public void fastjson2_jsonb(Blackhole bh) {
bh.consume(

View File

@ -14,8 +14,8 @@ public class EishayWriteStringTest {
}
long millis = System.currentTimeMillis() - start;
System.out.println("fastjson2 millis : " + millis);
// zulu8.70.0.23 : 3001
// zulu11.62.17 : 3288
// zulu8.70.0.23 : 3001 2873
// zulu11.62.17 : 3288 2974 3028
// zulu17.32.13 : 3305 2909
// zulu17.40.91_vec : 2527 2536
}

View File

@ -15,7 +15,7 @@ public class EishayWriteUTF8BytesTest {
long millis = System.currentTimeMillis() - start;
System.out.println("fastjson2 millis : " + millis);
// zulu8.58.0.13 : 336 347 317
// zulu11.52.13 : 337 314 289 2888 2606 2441
// zulu11.52.13 : 337 314 289 2888 2606 2441 2413 2401 2397
// zulu17.40.19 : 317 320 285
// zulu17.40.19_vec : 267 250
// graalvm_17.0.7 207

View File

@ -40,7 +40,7 @@ public class ClientsWriteUTF8BytesTest {
long millis = System.currentTimeMillis() - start;
System.out.println("ClientsWriteUTF8Bytes-fastjson2 millis : " + millis);
// zulu8.70.0.23 : 1533 1493 1374
// zulu17.40.19 : 1419 1361 1356 1356 1317 1224 1212 1202
// zulu17.40.19 : 1419 1361 1356 1356 1317 1224 1212 1202 1216
// zulu17.40.19_vec : 1116
// zulu17.40.19_reflect : 1427
}

View File

@ -28,6 +28,21 @@ public class BigDecimal200Test {
}
}
public static void fastjson2_ser() {
for (int j = 0; j < 10; j++) {
long start = System.currentTimeMillis();
for (int i = 0; i < 1000 * 1000; ++i) {
benchmark.fastjson2_ser(BH);
}
long millis = System.currentTimeMillis() - start;
System.out.println("BigDecimal20-fastjson2 : " + millis);
// zulu8.68.0.21 :
// zulu11.52.13 :
// zulu17.32.13 : 242
}
}
public static void fastjson2_jsonb() {
for (int j = 0; j < 10; j++) {
long start = System.currentTimeMillis();
@ -99,8 +114,9 @@ public class BigDecimal200Test {
public static void main(String[] args) throws Exception {
// fastjson2();
fastjson2_ser();
// fastjson2_jsonb();
// jackson();
wastjson();
// wastjson();
}
}

View File

@ -5,87 +5,83 @@ import static com.alibaba.fastjson2.benchmark.JMH.BH;
public class Int20Test {
static final IntValue20 benchmark = new IntValue20();
public static void fastjson2_test() {
for (int i = 0; i < 10; i++) {
fastjson2_perf();
public static void fastjson2() {
for (int j = 0; j < 10; j++) {
long start = System.currentTimeMillis();
for (int i = 0; i < 1000 * 1000; ++i) {
benchmark.fastjson2(BH);
}
long millis = System.currentTimeMillis() - start;
System.out.println("Int20Field-fastjson2 : " + millis);
// zulu8.62.0.19 : 445
// zulu11.52.13 : 427
// zulu17.32.13 : 433
}
}
public static void fastjson2_perf() {
long start = System.currentTimeMillis();
for (int i = 0; i < 1000 * 1000; ++i) {
benchmark.fastjson2(BH);
}
long millis = System.currentTimeMillis() - start;
System.out.println("Int20Field-fastjson2 : " + millis);
public static void fastjson2_ser() {
for (int j = 0; j < 10; j++) {
long start = System.currentTimeMillis();
for (int i = 0; i < 1000 * 1000; ++i) {
benchmark.fastjson2_ser(BH);
}
long millis = System.currentTimeMillis() - start;
System.out.println("Int20Field-fastjson2_ser : " + millis);
// zulu8.62.0.19 : 445
// zulu11.52.13 : 427
// zulu17.32.13 : 433
// zulu18.28.13 :
// zulu19.0.47 :
// corretto-8 :
// corretto-11 :
// corretto-17 :
// corretto-18 :
// oracle-jdk-17.0.4 :
// oracle-jdk-18.0.2 :
}
public static void jackson_test() throws Exception {
for (int i = 0; i < 10; i++) {
jackson();
// zulu8.62.0.19 : 118
// zulu11.52.13 :
// zulu17.32.13 :
}
}
public static void jackson() throws Exception {
long start = System.currentTimeMillis();
for (int i = 0; i < 1000 * 1000; ++i) {
benchmark.jackson(BH);
}
long millis = System.currentTimeMillis() - start;
System.out.println("Int20Field-jackson : " + millis);
// zulu8.62.0.19 : 886
// zulu11.52.13 : 964
// zulu17.32.13 : 975
// zulu18.28.13 :
// zulu19.0.47 :
// corretto-8 :
// corretto-11 :
// corretto-17 :
// corretto-18 :
// oracle-jdk-17.0.4 :
// oracle-jdk-18.0.2 :
}
public static void wastjson_test() throws Exception {
for (int i = 0; i < 10; i++) {
wastjson();
for (int j = 0; j < 10; j++) {
long start = System.currentTimeMillis();
for (int i = 0; i < 1000 * 1000; ++i) {
benchmark.jackson(BH);
}
long millis = System.currentTimeMillis() - start;
System.out.println("Int20Field-jackson : " + millis);
// zulu8.62.0.19 : 886
// zulu11.52.13 : 964
// zulu17.32.13 : 975
// zulu18.28.13 :
// zulu19.0.47 :
// corretto-8 :
// corretto-11 :
// corretto-17 :
// corretto-18 :
// oracle-jdk-17.0.4 :
// oracle-jdk-18.0.2 :
}
}
public static void wastjson() throws Exception {
long start = System.currentTimeMillis();
for (int i = 0; i < 1000 * 1000; ++i) {
benchmark.wastjson(BH);
for (int j = 0; j < 10; j++) {
long start = System.currentTimeMillis();
for (int i = 0; i < 1000 * 1000; ++i) {
benchmark.wastjson(BH);
}
long millis = System.currentTimeMillis() - start;
System.out.println("Int20Field-wastjson : " + millis);
// zulu8.62.0.19 : 505
// zulu11.52.13 : 412
// zulu17.32.13 : 434
// zulu18.28.13 :
// zulu19.0.47 :
// corretto-8 :
// corretto-11 :
// corretto-17 :
// corretto-18 :
// oracle-jdk-17.0.4 :
// oracle-jdk-18.0.2 :
}
long millis = System.currentTimeMillis() - start;
System.out.println("Int20Field-wastjson : " + millis);
// zulu8.62.0.19 : 505
// zulu11.52.13 : 412
// zulu17.32.13 : 434
// zulu18.28.13 :
// zulu19.0.47 :
// corretto-8 :
// corretto-11 :
// corretto-17 :
// corretto-18 :
// oracle-jdk-17.0.4 :
// oracle-jdk-18.0.2 :
}
public static void main(String[] args) throws Exception {
fastjson2_test();
// fastjson2();
fastjson2_ser();
// jackson_test();
// wastjson_test();
}

View File

@ -226,7 +226,7 @@ public class CodeGenUtils {
int size = IOUtils.stringSize(i);
byte[] chars = new byte[baseSize + size];
base.getBytes(0, baseSize, chars, 0);
IOUtils.writeInt32(chars, baseSize, i);
IOUtils.getChars(i, chars.length, chars);
return new String(chars);
}

View File

@ -1279,7 +1279,7 @@ class JSONWriterUTF16
&& (value.compareTo(LOW) < 0 || value.compareTo(HIGH) > 0));
int off = this.off;
int minCapacity = off + precision + 7;
int minCapacity = off + precision + 8;
if (minCapacity >= chars.length) {
ensureCapacity(minCapacity);
}
@ -1573,7 +1573,7 @@ class JSONWriterUTF16
boolean writeAsString = (context.features & Feature.WriteNonStringValueAsString.mask) != 0;
int off = this.off;
int minCapacity = off + value.length * 13 + 2;
int minCapacity = off + value.length * 13 + 3;
if (minCapacity >= chars.length) {
ensureCapacity(minCapacity);
}
@ -1624,7 +1624,7 @@ class JSONWriterUTF16
boolean writeAsString = (context.features & Feature.WriteNonStringValueAsString.mask) != 0;
int off = this.off;
int minCapacity = off + 7;
int minCapacity = off + 9;
if (minCapacity >= chars.length) {
ensureCapacity(minCapacity);
}
@ -1645,7 +1645,7 @@ class JSONWriterUTF16
boolean writeAsString = (context.features & Feature.WriteNonStringValueAsString.mask) != 0;
int off = this.off;
int minCapacity = off + 13;
int minCapacity = off + 14;
if (minCapacity >= chars.length) {
ensureCapacity(minCapacity);
}
@ -1682,7 +1682,7 @@ class JSONWriterUTF16
boolean nonStringAsString = (features & (WriteNonStringValueAsString.mask | WriteLongAsString.mask)) != 0;
int off = this.off;
int minCapacity = off + 2 + values.length * 23;
int minCapacity = off + 3 + values.length * 23;
if (minCapacity >= chars.length) {
ensureCapacity(minCapacity);
}
@ -1720,7 +1720,7 @@ class JSONWriterUTF16
int size = values.size();
boolean writeAsString = (context.features & Feature.WriteNonStringValueAsString.mask) != 0;
int off = this.off;
int minCapacity = off + 2 + size * 23;
int minCapacity = off + 3 + size * 13;
if (minCapacity >= chars.length) {
ensureCapacity(minCapacity);
}
@ -1768,7 +1768,7 @@ class JSONWriterUTF16
boolean browserCompatible = (features & BrowserCompatible.mask) != 0;
boolean nonStringAsString = (features & (WriteNonStringValueAsString.mask | WriteLongAsString.mask)) != 0;
int off = this.off;
int minCapacity = off + 2 + size * 23;
int minCapacity = off + 3 + size * 23;
if (minCapacity >= chars.length) {
ensureCapacity(minCapacity);
}
@ -1812,7 +1812,7 @@ class JSONWriterUTF16
boolean writeAsString = (features & (WriteNonStringValueAsString.mask | WriteLongAsString.mask)) != 0
|| ((features & BrowserCompatible.mask) != 0 && (i > 9007199254740991L || i < -9007199254740991L));
int off = this.off;
int minCapacity = off + 23;
int minCapacity = off + 24;
if (minCapacity >= chars.length) {
ensureCapacity(minCapacity);
}
@ -2026,33 +2026,33 @@ class JSONWriterUTF16
ensureCapacity(minCapacity);
}
final char[] bytes = this.chars;
bytes[off] = quote;
final char[] chars = this.chars;
chars[off] = quote;
if (year < 0 || year > 9999) {
throw new IllegalArgumentException("Only 4 digits numbers are supported. Provided: " + year);
}
final int q = year / 1000;
int v = DIGITS_K[year - q * 1000];
bytes[off + 1] = (char) (byte) (q + '0');
bytes[off + 2] = (char) (byte) (v >> 16);
bytes[off + 3] = (char) (byte) (v >> 8);
bytes[off + 4] = (char) (byte) v;
chars[off + 1] = (char) (byte) (q + '0');
chars[off + 2] = (char) (byte) (v >> 8);
chars[off + 3] = (char) (byte) (v >> 16);
chars[off + 4] = (char) (byte) (v >> 24);
v = DIGITS_K[month];
bytes[off + 5] = (char) (byte) (v >> 8);
bytes[off + 6] = (char) (byte) v;
chars[off + 5] = (char) (byte) (v >> 16);
chars[off + 6] = (char) (byte) (v >> 24);
v = DIGITS_K[dayOfMonth];
bytes[off + 7] = (char) (byte) (v >> 8);
bytes[off + 8] = (char) (byte) v;
chars[off + 7] = (char) (byte) (v >> 16);
chars[off + 8] = (char) (byte) (v >> 24);
v = DIGITS_K[hour];
bytes[off + 9] = (char) (byte) (v >> 8);
bytes[off + 10] = (char) (byte) v;
chars[off + 9] = (char) (byte) (v >> 16);
chars[off + 10] = (char) (byte) (v >> 24);
v = DIGITS_K[minute];
bytes[off + 11] = (char) (byte) (v >> 8);
bytes[off + 12] = (char) (byte) v;
chars[off + 11] = (char) (byte) (v >> 16);
chars[off + 12] = (char) (byte) (v >> 24);
v = DIGITS_K[second];
bytes[off + 13] = (char) (byte) (v >> 8);
bytes[off + 14] = (char) (byte) v;
bytes[off + 15] = quote;
chars[off + 13] = (char) (byte) (v >> 16);
chars[off + 14] = (char) (byte) (v >> 24);
chars[off + 15] = quote;
this.off = off + 16;
}
@ -2075,29 +2075,29 @@ class JSONWriterUTF16
final int q = year / 1000;
int v = DIGITS_K[year - q * 1000];
chars[off + 1] = (char) (byte) (q + '0');
chars[off + 2] = (char) (byte) (v >> 16);
chars[off + 3] = (char) (byte) (v >> 8);
chars[off + 4] = (char) (byte) v;
chars[off + 2] = (char) (byte) (v >> 8);
chars[off + 3] = (char) (byte) (v >> 16);
chars[off + 4] = (char) (byte) (v >> 24);
chars[off + 5] = '-';
v = DIGITS_K[month];
chars[off + 6] = (char) (byte) (v >> 8);
chars[off + 7] = (char) (byte) v;
chars[off + 6] = (char) (byte) (v >> 16);
chars[off + 7] = (char) (byte) (v >> 24);
chars[off + 8] = '-';
v = DIGITS_K[dayOfMonth];
chars[off + 9] = (char) (byte) (v >> 8);
chars[off + 10] = (char) (byte) v;
chars[off + 9] = (char) (byte) (v >> 16);
chars[off + 10] = (char) (byte) (v >> 24);
chars[off + 11] = ' ';
v = DIGITS_K[hour];
chars[off + 12] = (char) (byte) (v >> 8);
chars[off + 13] = (char) (byte) v;
chars[off + 12] = (char) (byte) (v >> 16);
chars[off + 13] = (char) (byte) (v >> 24);
chars[off + 14] = ':';
v = DIGITS_K[minute];
chars[off + 15] = (char) (byte) (v >> 8);
chars[off + 16] = (char) (byte) v;
chars[off + 15] = (char) (byte) (v >> 16);
chars[off + 16] = (char) (byte) (v >> 24);
chars[off + 17] = ':';
v = DIGITS_K[second];
chars[off + 18] = (char) (byte) (v >> 8);
chars[off + 19] = (char) (byte) v;
chars[off + 18] = (char) (byte) (v >> 16);
chars[off + 19] = (char) (byte) (v >> 24);
chars[off + 20] = (char) (byte) quote;
this.off = off + 21;
}
@ -2131,7 +2131,7 @@ class JSONWriterUTF16
@Override
public final void writeLocalDateTime(LocalDateTime dateTime) {
int off = this.off;
int minCapacity = off + 38;
int minCapacity = off + 37;
if (minCapacity >= chars.length) {
ensureCapacity(minCapacity);
}
@ -2166,7 +2166,7 @@ class JSONWriterUTF16
}
int off = this.off;
int minCapacity = off + 25 + zonelen;
int minCapacity = off + 26 + zonelen;
if (off + minCapacity >= chars.length) {
ensureCapacity(minCapacity);
}
@ -2176,24 +2176,24 @@ class JSONWriterUTF16
off = IOUtils.writeInt32(bytes, off + 1, year);
bytes[off] = '-';
int v = DIGITS_K[month];
bytes[off + 1] = (char) (byte) (v >> 8);
bytes[off + 2] = (char) (byte) v;
bytes[off + 1] = (char) (byte) (v >> 16);
bytes[off + 2] = (char) (byte) (v >> 24);
bytes[off + 3] = '-';
v = DIGITS_K[dayOfMonth];
bytes[off + 4] = (char) (byte) (v >> 8);
bytes[off + 5] = (char) (byte) v;
bytes[off + 4] = (char) (byte) (v >> 16);
bytes[off + 5] = (char) (byte) (v >> 24);
bytes[off + 6] = (char) (byte) (timeZone ? 'T' : ' ');
v = DIGITS_K[hour];
bytes[off + 7] = (char) (byte) (v >> 8);
bytes[off + 8] = (char) (byte) v;
bytes[off + 7] = (char) (byte) (v >> 16);
bytes[off + 8] = (char) (byte) (v >> 24);
bytes[off + 9] = ':';
v = DIGITS_K[minute];
bytes[off + 10] = (char) (byte) (v >> 8);
bytes[off + 11] = (char) (byte) v;
bytes[off + 10] = (char) (byte) (v >> 16);
bytes[off + 11] = (char) (byte) (v >> 24);
bytes[off + 12] = ':';
v = DIGITS_K[second];
bytes[off + 13] = (char) (byte) (v >> 8);
bytes[off + 14] = (char) (byte) v;
bytes[off + 13] = (char) (byte) (v >> 16);
bytes[off + 14] = (char) (byte) (v >> 24);
off += 15;
if (millis > 0) {
@ -2204,16 +2204,16 @@ class JSONWriterUTF16
if (rem1 != 0) {
v = DIGITS_K[millis];
bytes[off] = (char) (byte) (v >> 16);
bytes[off + 1] = (char) (byte) (v >> 8);
bytes[off + 2] = (char) (byte) v;
bytes[off] = (char) (byte) (v >> 8);
bytes[off + 1] = (char) (byte) (v >> 16);
bytes[off + 2] = (char) (byte) (v >> 24);
off += 3;
} else {
final int rem2 = div - div2 * 10;
if (rem2 != 0) {
v = DIGITS_K[div];
bytes[off] = (char) (byte) (v >> 8);
bytes[off + 1] = (char) (byte) v;
bytes[off] = (char) (byte) (v >> 16);
bytes[off + 1] = (char) (byte) (v >> 24);
off += 2;
} else {
bytes[off++] = (char) (byte) (div2 + '0');
@ -2229,16 +2229,16 @@ class JSONWriterUTF16
int offsetAbs = Math.abs(offset);
bytes[off] = offset >= 0 ? '+' : '-';
v = DIGITS_K[offsetAbs];
bytes[off + 1] = (char) (byte) (v >> 8);
bytes[off + 2] = (char) (byte) v;
bytes[off + 1] = (char) (byte) (v >> 16);
bytes[off + 2] = (char) (byte) (v >> 24);
bytes[off + 3] = ':';
int offsetMinutes = (offsetSeconds - offset * 3600) / 60;
if (offsetMinutes < 0) {
offsetMinutes = -offsetMinutes;
}
v = DIGITS_K[offsetMinutes];
bytes[off + 4] = (char) (byte) (v >> 8);
bytes[off + 5] = (char) (byte) v;
bytes[off + 4] = (char) (byte) (v >> 16);
bytes[off + 5] = (char) (byte) (v >> 24);
off += 6;
}
}
@ -2262,15 +2262,15 @@ class JSONWriterUTF16
final int q = year / 1000;
int v = DIGITS_K[year - q * 1000];
chars[off + 1] = (char) (byte) (q + '0');
chars[off + 2] = (char) (byte) (v >> 16);
chars[off + 3] = (char) (byte) (v >> 8);
chars[off + 4] = (char) (byte) v;
chars[off + 2] = (char) (byte) (v >> 8);
chars[off + 3] = (char) (byte) (v >> 16);
chars[off + 4] = (char) (byte) (v >> 24);
v = DIGITS_K[month];
chars[off + 5] = (char) (byte) (v >> 8);
chars[off + 6] = (char) (byte) v;
chars[off + 5] = (char) (byte) (v >> 16);
chars[off + 6] = (char) (byte) (v >> 24);
v = DIGITS_K[dayOfMonth];
chars[off + 7] = (char) (byte) (v >> 8);
chars[off + 8] = (char) (byte) v;
chars[off + 7] = (char) (byte) (v >> 16);
chars[off + 8] = (char) (byte) (v >> 24);
chars[off + 9] = quote;
this.off = off + 10;
}
@ -2301,16 +2301,16 @@ class JSONWriterUTF16
final char[] chars = this.chars;
chars[off] = (char) (byte) quote;
int v = DIGITS_K[hour];
chars[off + 1] = (char) (byte) (v >> 8);
chars[off + 2] = (char) (byte) v;
chars[off + 1] = (char) (byte) (v >> 16);
chars[off + 2] = (char) (byte) (v >> 24);
chars[off + 3] = ':';
v = DIGITS_K[minute];
chars[off + 4] = (char) (byte) (v >> 8);
chars[off + 5] = (char) (byte) v;
chars[off + 4] = (char) (byte) (v >> 16);
chars[off + 5] = (char) (byte) (v >> 24);
chars[off + 6] = ':';
v = DIGITS_K[second];
chars[off + 7] = (char) (byte) (v >> 8);
chars[off + 8] = (char) (byte) v;
chars[off + 7] = (char) (byte) (v >> 16);
chars[off + 8] = (char) (byte) (v >> 24);
chars[off + 9] = (char) (byte) quote;
this.off = off + 10;
}
@ -2318,7 +2318,7 @@ class JSONWriterUTF16
@Override
public final void writeLocalTime(LocalTime time) {
int off = this.off;
int minCapacity = off + 20;
int minCapacity = off + 21;
if (minCapacity >= chars.length) {
ensureCapacity(minCapacity);
}
@ -2352,7 +2352,7 @@ class JSONWriterUTF16
}
int off = this.off;
int minCapacity = off + zoneSize + 38;
int minCapacity = off + zoneSize + 39;
if (minCapacity >= chars.length) {
ensureCapacity(minCapacity);
}
@ -2395,7 +2395,7 @@ class JSONWriterUTF16
}
int off = this.off;
int minCapacity = off + zoneIdLength + 40;
int minCapacity = off + zoneIdLength + 41;
if (minCapacity >= chars.length) {
ensureCapacity(minCapacity);
}

View File

@ -21,22 +21,6 @@ import static com.alibaba.fastjson2.util.JDKUtils.*;
class JSONWriterUTF8
extends JSONWriter {
static final byte[] REF_PREF = "{\"$ref\":".getBytes(StandardCharsets.ISO_8859_1);
static final short[] HEX256;
static {
short[] digits = new short[16 * 16];
for (int i = 0; i < 16; i++) {
short hi = (short) (i < 10 ? i + '0' : i - 10 + 'a');
for (int j = 0; j < 16; j++) {
short lo = (short) (j < 10 ? j + '0' : j - 10 + 'a');
digits[(i << 4) + j] = BIG_ENDIAN ? (short) ((hi << 8) | lo) : (short) (hi | (lo << 8));
}
}
HEX256 = digits;
}
final CacheItem cacheItem;
protected byte[] bytes;
@ -1423,30 +1407,6 @@ class JSONWriterUTF8
this.off = off + 1;
}
/**
* Return a big-endian packed integer for the 4 ASCII bytes for an input unsigned 2-byte integer.
* {@code b0} is the most significant byte and {@code b1} is the least significant byte.
* The integer is passed byte-wise to allow reordering of execution.
*/
static int packDigits(int b0, int b1) {
int v = HEX256[b0 & 0xff] | (HEX256[b1 & 0xff] << 16);
return BIG_ENDIAN ? Integer.reverseBytes(v) : v;
}
/**
* Return a big-endian packed long for the 8 ASCII bytes for an input unsigned 4-byte integer.
* {@code b0} is the most significant byte and {@code b3} is the least significant byte.
* The integer is passed byte-wise to allow reordering of execution.
*/
static long packDigits(int b0, int b1, int b2, int b3) {
short[] digits = HEX256;
long v = (digits[b0 & 0xff]
| (((long) digits[b1 & 0xff]) << 16)
| (((long) digits[b2 & 0xff]) << 32))
| (((long) digits[b3 & 0xff]) << 48);
return BIG_ENDIAN ? Long.reverseBytes(v) : v;
}
@Override
public final void writeUUID(UUID value) {
if (value == null) {
@ -1818,7 +1778,7 @@ class JSONWriterUTF8
boolean writeAsString = (context.features & Feature.WriteNonStringValueAsString.mask) != 0;
int off = this.off;
int minCapacity = off + values.length * 13 + 2;
int minCapacity = off + values.length * 14 + 2;
if (minCapacity >= bytes.length) {
ensureCapacity(minCapacity);
}
@ -1848,7 +1808,7 @@ class JSONWriterUTF8
boolean writeAsString = (context.features & Feature.WriteNonStringValueAsString.mask) != 0;
int off = this.off;
int minCapacity = off + 5;
int minCapacity = off + 7;
if (minCapacity >= bytes.length) {
ensureCapacity(minCapacity);
}
@ -1869,7 +1829,7 @@ class JSONWriterUTF8
boolean writeAsString = (context.features & Feature.WriteNonStringValueAsString.mask) != 0;
int off = this.off;
int minCapacity = off + 7;
int minCapacity = off + 9;
if (minCapacity >= bytes.length) {
ensureCapacity(minCapacity);
}
@ -1899,7 +1859,7 @@ class JSONWriterUTF8
boolean writeAsString = (context.features & Feature.WriteNonStringValueAsString.mask) != 0;
int off = this.off;
int minCapacity = off + 13;
int minCapacity = off + 14;
if (minCapacity >= bytes.length) {
ensureCapacity(minCapacity);
}
@ -1925,7 +1885,7 @@ class JSONWriterUTF8
int size = values.size();
boolean writeAsString = (context.features & Feature.WriteNonStringValueAsString.mask) != 0;
int off = this.off;
int minCapacity = off + 2 + size * 23;
int minCapacity = off + 2 + size * 14;
if (minCapacity >= bytes.length) {
ensureCapacity(minCapacity);
}
@ -2050,7 +2010,7 @@ class JSONWriterUTF8
boolean writeAsString = (features & (WriteNonStringValueAsString.mask | WriteLongAsString.mask)) != 0
|| ((features & BrowserCompatible.mask) != 0 && (i > 9007199254740991L || i < -9007199254740991L));
int off = this.off;
int minCapacity = off + 23;
int minCapacity = off + 24;
if (minCapacity >= bytes.length) {
ensureCapacity(minCapacity);
}
@ -2219,32 +2179,31 @@ class JSONWriterUTF8
}
final byte[] bytes = this.bytes;
bytes[off] = (byte) quote;
if (year < 0 || year > 9999) {
throw new IllegalArgumentException("Only 4 digits numbers are supported. Provided: " + year);
}
final int q = year / 1000;
int v = DIGITS_K[year - q * 1000];
bytes[off + 1] = (byte) (q + '0');
bytes[off + 2] = (byte) (v >> 16);
bytes[off + 3] = (byte) (v >> 8);
bytes[off + 4] = (byte) v;
v = DIGITS_K[month];
bytes[off + 5] = (byte) (v >> 8);
bytes[off + 6] = (byte) v;
v = DIGITS_K[dayOfMonth];
bytes[off + 7] = (byte) (v >> 8);
bytes[off + 8] = (byte) v;
v = DIGITS_K[hour];
bytes[off + 9] = (byte) (v >> 8);
bytes[off + 10] = (byte) v;
v = DIGITS_K[minute];
bytes[off + 11] = (byte) (v >> 8);
bytes[off + 12] = (byte) v;
v = DIGITS_K[second];
bytes[off + 13] = (byte) (v >> 8);
bytes[off + 14] = (byte) v;
bytes[off + 15] = (byte) quote;
bytes[off] = (byte) quote;
int v = DIGITS_K[dayOfMonth];
putLong(
bytes,
off,
quote
+ ((q + '0') << 8)
+ ((DIGITS_K[year - q * 1000] & 0xffffff00L) << 8)
+ ((DIGITS_K[month] & 0xffff0000L) << 24)
+ ((v & 0xff_0000L) << 40)
);
putLong(
bytes,
off + 8,
((v & 0xff000000L) >> 24)
+ ((DIGITS_K[hour] & 0xffff0000L) >> 8)
+ ((DIGITS_K[minute] & 0xffff0000L) << 8)
+ ((DIGITS_K[second] & 0xffff0000L) << 24)
+ (((long) quote) << 56)
);
this.off = off + 16;
}
@ -2263,36 +2222,37 @@ class JSONWriterUTF8
}
final byte[] bytes = this.bytes;
bytes[off] = (byte) quote;
if (year < 0 || year > 9999) {
throw new IllegalArgumentException("Only 4 digits numbers are supported. Provided: " + year);
}
final int q = year / 1000;
int v = DIGITS_K[year - q * 1000];
bytes[off + 1] = (byte) (q + '0');
bytes[off + 2] = (byte) (v >> 16);
bytes[off + 3] = (byte) (v >> 8);
bytes[off + 4] = (byte) v;
bytes[off + 5] = '-';
v = DIGITS_K[month];
bytes[off + 6] = (byte) (v >> 8);
bytes[off + 7] = (byte) v;
bytes[off + 8] = '-';
v = DIGITS_K[dayOfMonth];
bytes[off + 9] = (byte) (v >> 8);
bytes[off + 10] = (byte) v;
bytes[off + 11] = ' ';
v = DIGITS_K[hour];
bytes[off + 12] = (byte) (v >> 8);
bytes[off + 13] = (byte) v;
bytes[off + 14] = ':';
v = DIGITS_K[minute];
bytes[off + 15] = (byte) (v >> 8);
bytes[off + 16] = (byte) v;
bytes[off + 17] = ':';
v = DIGITS_K[second];
bytes[off + 18] = (byte) (v >> 8);
bytes[off + 19] = (byte) v;
putLong(
bytes,
off,
quote
+ ((q + '0') << 8)
+ ((DIGITS_K[year - q * 1000] & 0xffffff00L) << 8)
+ 0x2d00_0000_0000L
+ ((DIGITS_K[month] & 0xffff0000L) << 32)
);
putInt(
bytes,
off + 8,
0x2000_002d
+ ((DIGITS_K[dayOfMonth] & 0xffff0000) >> 8)
);
putLong(
bytes,
off + 12,
((DIGITS_K[hour] & 0xffff0000L) >> 16)
+ 0x3a00003a0000L
+ ((DIGITS_K[minute] & 0xffff0000L) << 8)
+ ((DIGITS_K[second] & 0xffff0000L) << 32)
);
bytes[off + 20] = (byte) quote;
this.off = off + 21;
}
@ -2355,17 +2315,14 @@ class JSONWriterUTF8
throw new IllegalArgumentException("Only 4 digits numbers are supported. Provided: " + year);
}
final int q = year / 1000;
int v = DIGITS_K[year - q * 1000];
bytes[off + 1] = (byte) (q + '0');
bytes[off + 2] = (byte) (v >> 16);
bytes[off + 3] = (byte) (v >> 8);
bytes[off + 4] = (byte) v;
v = DIGITS_K[month];
bytes[off + 5] = (byte) (v >> 8);
bytes[off + 6] = (byte) v;
v = DIGITS_K[dayOfMonth];
bytes[off + 7] = (byte) (v >> 8);
bytes[off + 8] = (byte) v;
putLong(
bytes,
off + 1,
+(q + '0')
+ (DIGITS_K[year - q * 1000] & 0xffffff00L)
+ ((DIGITS_K[month] & 0xffff_0000L) << 16)
+ ((DIGITS_K[dayOfMonth] & 0xffff0000L) << 32)
);
bytes[off + 9] = (byte) quote;
this.off = off + 10;
}
@ -2395,17 +2352,16 @@ class JSONWriterUTF8
final byte[] bytes = this.bytes;
bytes[off] = (byte) quote;
int v = DIGITS_K[hour];
bytes[off + 1] = (byte) (v >> 8);
bytes[off + 2] = (byte) v;
bytes[off + 3] = ':';
v = DIGITS_K[minute];
bytes[off + 4] = (byte) (v >> 8);
bytes[off + 5] = (byte) v;
bytes[off + 6] = ':';
v = DIGITS_K[second];
bytes[off + 7] = (byte) (v >> 8);
bytes[off + 8] = (byte) v;
putLong(
bytes,
off + 1,
((DIGITS_K[hour] & 0xffff0000L) >> 16)
+ 0x3a00003a0000L
+ ((DIGITS_K[minute] & 0xffff0000L) << 8)
+ ((DIGITS_K[second] & 0xffff0000L) << 32)
);
bytes[off + 9] = (byte) quote;
this.off = off + 10;
}
@ -2555,14 +2511,7 @@ class JSONWriterUTF8
int offsetSeconds,
boolean timeZone
) {
int zonelen;
if (timeZone) {
zonelen = offsetSeconds == 0 ? 1 : 6;
} else {
zonelen = 0;
}
int minCapacity = off + 25 + zonelen;
int minCapacity = off + 32;
if (minCapacity >= bytes.length) {
ensureCapacity(minCapacity);
}
@ -2571,46 +2520,41 @@ class JSONWriterUTF8
int off = this.off;
bytes[off] = (byte) quote;
off = IOUtils.writeInt32(bytes, off + 1, year);
bytes[off] = '-';
int v = DIGITS_K[month];
bytes[off + 1] = (byte) (v >> 8);
bytes[off + 2] = (byte) v;
bytes[off + 3] = '-';
v = DIGITS_K[dayOfMonth];
bytes[off + 4] = (byte) (v >> 8);
bytes[off + 5] = (byte) v;
bytes[off + 6] = (byte) (timeZone ? 'T' : ' ');
v = DIGITS_K[hour];
bytes[off + 7] = (byte) (v >> 8);
bytes[off + 8] = (byte) v;
bytes[off + 9] = ':';
v = DIGITS_K[minute];
bytes[off + 10] = (byte) (v >> 8);
bytes[off + 11] = (byte) v;
bytes[off + 12] = ':';
v = DIGITS_K[second];
bytes[off + 13] = (byte) (v >> 8);
bytes[off + 14] = (byte) v;
putLong(
bytes,
off,
((DIGITS_K[month] & 0xffff0000L) >> 8)
+ ((DIGITS_K[dayOfMonth] & 0xffff0000L) << 16)
+ (timeZone ? 0x54_0000_2d00_002dL : 0x20_0000_2d00_002dL)
);
putLong(
bytes,
off + 7,
((DIGITS_K[hour] & 0xffff0000L) >> 16)
+ 0x3a00003a_0000L
+ ((DIGITS_K[minute] & 0xffff0000L) << 8)
+ ((DIGITS_K[second] & 0xffff0000L) << 32)
);
off += 15;
if (millis > 0) {
bytes[off++] = '.';
int div = millis / 10;
int div2 = div / 10;
final int rem1 = millis - div * 10;
if (rem1 != 0) {
v = DIGITS_K[millis];
bytes[off] = (byte) (v >> 16);
bytes[off + 1] = (byte) (v >> 8);
bytes[off + 2] = (byte) v;
off += 3;
putInt(bytes, off, '.' + (DIGITS_K[millis] & 0xffffff00));
off += 4;
} else {
bytes[off++] = '.';
final int rem2 = div - div2 * 10;
if (rem2 != 0) {
v = DIGITS_K[div];
bytes[off] = (byte) (v >> 8);
bytes[off + 1] = (byte) v;
int v = DIGITS_K[div];
bytes[off] = (byte) (v >> 16);
bytes[off + 1] = (byte) (v >> 24);
off += 2;
} else {
bytes[off++] = (byte) (div2 + '0');
@ -2625,17 +2569,17 @@ class JSONWriterUTF8
} else {
int offsetAbs = Math.abs(offset);
bytes[off] = offset >= 0 ? (byte) '+' : (byte) '-';
v = DIGITS_K[offsetAbs];
bytes[off + 1] = (byte) (v >> 8);
bytes[off + 2] = (byte) v;
int v = DIGITS_K[offsetAbs];
bytes[off + 1] = (byte) (v >> 16);
bytes[off + 2] = (byte) (v >> 24);
bytes[off + 3] = ':';
int offsetMinutes = (offsetSeconds - offset * 3600) / 60;
if (offsetMinutes < 0) {
offsetMinutes = -offsetMinutes;
}
v = DIGITS_K[offsetMinutes];
bytes[off + 4] = (byte) (v >> 8);
bytes[off + 5] = (byte) v;
bytes[off + 4] = (byte) (v >> 16);
bytes[off + 5] = (byte) (v >> 24);
off += 6;
}
}
@ -2666,7 +2610,7 @@ class JSONWriterUTF8
&& (value.compareTo(LOW) < 0 || value.compareTo(HIGH) > 0));
int off = this.off;
int minCapacity = off + precision + 7;
int minCapacity = off + precision + 8;
if (minCapacity >= bytes.length) {
ensureCapacity(minCapacity);
}

View File

@ -43,7 +43,7 @@ public class CodeGenUtils {
int size = IOUtils.stringSize(i);
char[] chars = new char[baseSize + size];
base.getChars(0, baseSize, chars, 0);
IOUtils.writeInt32(chars, baseSize, i);
IOUtils.getChars(i, chars.length, chars);
return new String(chars);
}
}

View File

@ -18,7 +18,6 @@ final class CSVWriterUTF16
extends CSVWriter {
static final char[] BYTES_TRUE = "true".toCharArray();
static final char[] BYTES_FALSE = "false".toCharArray();
static final char[] BYTES_LONG_MIN = "-9223372036854775808".toCharArray();
final Writer out;
final char[] chars;
@ -100,16 +99,16 @@ final class CSVWriterUTF16
off = IOUtils.writeLocalDate(chars, off, year, month, dayOfMonth);
chars[off] = ' ';
int v = DIGITS_K[hour];
chars[off + 1] = (char) (byte) (v >> 8);
chars[off + 2] = (char) (byte) v;
chars[off + 1] = (char) (byte) (v >> 16);
chars[off + 2] = (char) (byte) (v >> 24);
chars[off + 3] = ':';
v = DIGITS_K[minute];
chars[off + 4] = (char) (byte) (v >> 8);
chars[off + 5] = (char) (byte) v;
chars[off + 4] = (char) (byte) (v >> 16);
chars[off + 5] = (char) (byte) (v >> 24);
chars[off + 6] = ':';
v = DIGITS_K[second];
chars[off + 7] = (char) (byte) (v >> 8);
chars[off + 8] = (char) (byte) v;
chars[off + 7] = (char) (byte) (v >> 16);
chars[off + 8] = (char) (byte) (v >> 24);
this.off = off + 9;
}
@ -167,7 +166,7 @@ final class CSVWriterUTF16
}
public void writeInt32(int intValue) {
int minCapacity = off + 11;
int minCapacity = off + 12;
if (minCapacity - this.chars.length > 0) {
flush();
}
@ -236,7 +235,7 @@ final class CSVWriterUTF16
return;
}
int minCapacity = off + 24;
int minCapacity = off + 25;
if (minCapacity - this.chars.length > 0) {
flush();
}
@ -264,6 +263,11 @@ final class CSVWriterUTF16
return;
}
int minCapacity = off + 16;
if (minCapacity - this.chars.length > 0) {
flush();
}
off = IOUtils.writeLocalDate(chars, off, ldt.getYear(), ldt.getMonthValue(), ldt.getDayOfMonth());
chars[off++] = ' ';
off = IOUtils.writeLocalTime(chars, off, ldt.toLocalTime());

View File

@ -13,12 +13,12 @@ import java.time.LocalDateTime;
import java.time.ZoneId;
import static com.alibaba.fastjson2.util.IOUtils.DIGITS_K;
import static com.alibaba.fastjson2.util.IOUtils.putLong;
final class CSVWriterUTF8
extends CSVWriter {
static final byte[] BYTES_TRUE = "true".getBytes();
static final byte[] BYTES_FALSE = "false".getBytes();
static final byte[] BYTES_LONG_MIN = "-9223372036854775808".getBytes();
final OutputStream out;
final Charset charset;
@ -103,17 +103,14 @@ final class CSVWriterUTF8
int off = this.off;
off = IOUtils.writeLocalDate(bytes, off, year, month, dayOfMonth);
bytes[off] = ' ';
int v = DIGITS_K[hour];
bytes[off + 1] = (byte) (v >> 8);
bytes[off + 2] = (byte) v;
bytes[off + 3] = ':';
v = DIGITS_K[minute];
bytes[off + 4] = (byte) (v >> 8);
bytes[off + 5] = (byte) v;
bytes[off + 6] = ':';
v = DIGITS_K[second];
bytes[off + 7] = (byte) (v >> 8);
bytes[off + 8] = (byte) v;
putLong(
bytes,
off + 1,
((DIGITS_K[hour] & 0xffff0000L) >> 16)
+ 0x3a00003a0000L
+ ((DIGITS_K[minute] & 0xffff0000L) << 8)
+ ((DIGITS_K[second] & 0xffff0000L) << 32)
);
this.off = off + 9;
}
@ -130,7 +127,7 @@ final class CSVWriterUTF8
}
public void writeInt32(int intValue) {
int minCapacity = off + 11;
int minCapacity = off + 12;
if (minCapacity - this.bytes.length > 0) {
flush();
}
@ -239,7 +236,7 @@ final class CSVWriterUTF8
return;
}
int minCapacity = off + 24;
int minCapacity = off + 25;
if (minCapacity - this.bytes.length > 0) {
flush();
}

File diff suppressed because it is too large Load Diff

View File

@ -28,9 +28,9 @@ public class LocalDateTest {
@Test
public void test0_x() {
Bean bean = new Bean();
bean.date = LocalDate.of(2017, 9, 11);
bean.date = LocalDate.of(2017, 9, 12);
String str = JSON.toJSONString(bean);
assertEquals("{\"date\":\"2017-09-11\"}", str);
assertEquals("{\"date\":\"2017-09-12\"}", str);
}
@Test

View File

@ -3,7 +3,11 @@ package com.alibaba.fastjson2.util;
import org.junit.jupiter.api.Test;
import java.nio.charset.StandardCharsets;
import java.time.LocalTime;
import static com.alibaba.fastjson2.util.IOUtils.DIGITS_K;
import static com.alibaba.fastjson2.util.IOUtils.DIGITS_K_64;
import static com.alibaba.fastjson2.util.JDKUtils.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class IOUtilsTest {
@ -140,4 +144,221 @@ public class IOUtilsTest {
assertEquals(str_n, new String(chars_n));
}
}
@Test
public void getCharsLong1() {
long[] values = new long[] {
1,
10,
12,
100,
123,
1000,
1234,
10000,
12345,
100000,
123456,
1000000,
1234567,
10000000,
12345678,
100000000,
123456789,
1000000000,
1234567891,
10000000000L,
12345678912L,
100000000000L,
123456789123L,
1000000000000L,
1234567891234L,
10000000000000L,
12345678912345L,
100000000000000L,
123456789123456L,
1000000000000000L,
1234567891234567L,
10000000000000000L,
12345678912345678L,
100000000000000000L,
123456789123456789L,
1000000000000000000L,
1234567891234567891L,
-1,
-10,
-12,
-100,
-123,
-1000,
-1234,
-10000,
-12345,
-100000,
-123456,
-1000000,
-1234567,
-10000000,
-12345678,
-100000000,
-123456789,
-1000000000,
-1234567891,
-10000000000L,
-12345678912L,
-100000000000L,
-123456789123L,
-1000000000000L,
-1234567891234L,
-10000000000000L,
-12345678912345L,
-100000000000000L,
-123456789123456L,
-1000000000000000L,
-1234567891234567L,
-10000000000000000L,
-12345678912345678L,
-100000000000000000L,
-123456789123456789L,
-1000000000000000000L,
-1234567891234567891L,
Long.MAX_VALUE,
Long.MIN_VALUE
};
for (int i = 0; i < values.length; i++) {
long d = values[i];
String str = Long.toString(d);
byte[] bytes = new byte[20];
int size = IOUtils.writeInt64(bytes, 0, d);
assertEquals(str.length(), size, str);
assertEquals(str, new String(bytes, 0, size), str);
char[] chars = new char[20];
int size1 = IOUtils.writeInt64(chars, 0, d);
assertEquals(str.length(), size1, str);
assertEquals(str, new String(chars, 0, size1), str);
}
}
@Test
public void getCharsInt1() {
int[] values = new int[] {
1,
10,
12,
100,
123,
1000,
1234,
10000,
12345,
100000,
123456,
1000000,
1234567,
10000000,
12345678,
100000000,
123456789,
1000000000,
1234567891,
-1,
-10,
-12,
-100,
-123,
-1000,
-1234,
-10000,
-12345,
-100000,
-123456,
-1000000,
-1234567,
-10000000,
-12345678,
-100000000,
-123456789,
-1000000000,
-1234567891,
Integer.MAX_VALUE,
Integer.MIN_VALUE
};
for (int i = 0; i < values.length; i++) {
int d = values[i];
String str = Integer.toString(d);
byte[] bytes = new byte[20];
int size = IOUtils.writeInt32(bytes, 0, d);
assertEquals(str.length(), size, str);
assertEquals(str.length(), size);
assertEquals(str, new String(bytes, 0, size), str);
char[] chars = new char[20];
int size1 = IOUtils.writeInt32(chars, 0, d);
assertEquals(str.length(), size1, str);
assertEquals(str, new String(chars, 0, size1), str);
}
}
@Test
public void digitK() {
int[] digits = DIGITS_K;
byte[] bytes = new byte[20];
for (int i = 0; i < digits.length; i++) {
String str = Integer.toString(i);
int d = digits[i];
int size = (byte) d;
assertEquals(str.length(), size);
UNSAFE.putInt(bytes, ARRAY_BYTE_BASE_OFFSET, d >> ((4 - size) << 3));
String str1 = new String(bytes, 0, size);
assertEquals(str, str1);
}
}
@Test
public void digitK64() {
long[] digits = DIGITS_K_64;
char[] bytes = new char[20];
for (int i = 0; i < digits.length; i++) {
String str = Integer.toString(i);
long d = digits[i];
int size = (byte) d;
assertEquals(str.length(), size);
UNSAFE.putLong(bytes, ARRAY_CHAR_BASE_OFFSET, d >> ((4 - size) << 4));
String str1 = new String(bytes, 0, size);
assertEquals(str, str1);
}
}
@Test
public void writeLocalDate() {
char[] chars = new char[20];
int size = IOUtils.writeLocalDate(chars, 0, 2013, 12, 30);
assertEquals("2013-12-30", new String(chars, 0, size));
}
@Test
public void writeLocalTime() {
char[] chars = new char[20];
int size = IOUtils.writeLocalTime(chars, 0, LocalTime.of(12, 13, 14));
assertEquals("12:13:14", new String(chars, 0, size));
}
@Test
public void writeLocalTime1() {
char[] chars = new char[18];
int size = IOUtils.writeLocalTime(chars, 0, LocalTime.of(12, 13, 14, 123456789));
assertEquals("12:13:14.123456789", new String(chars, 0, size));
}
}

View File

@ -0,0 +1,13 @@
package com.alibaba.fastjson2.util.internal;
import com.alibaba.fastjson2.internal.CodeGenUtils;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class CodeGenUtilsTest {
@Test
public void test() {
assertEquals("fieldReader123", CodeGenUtils.fieldReader(123));
}
}

View File

@ -59,11 +59,8 @@ public class JSONExtractScalar
@Override
public void accept(int val) {
int size = (val < 0) ? IOUtils.stringSize(-val) + 1 : IOUtils.stringSize(val);
text.setCapacity(size, false);
byte[] bytes = text.bytes;
IOUtils.getChars(val, size, bytes);
text.length = size;
text.setCapacity(13, false);
text.length = IOUtils.writeInt32(text.bytes, 0, val);
}
@Override

View File

@ -74,8 +74,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>11</source>
<target>11</target>
<source>17</source>
<target>17</target>
<compilerArgs combine.children="append">
<arg>${add.modules.option}</arg>
</compilerArgs>