Skip to content

Commit 67b2296

Browse files
committed
improved parseDouble & parseFloat perforamnce
1 parent 0d642c9 commit 67b2296

File tree

4 files changed

+325
-1
lines changed

4 files changed

+325
-1
lines changed

src/main/java/com/alibaba/fastjson/parser/deserializer/JavaBeanDeserializer.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1359,13 +1359,31 @@ public Object createInstance(Map<String, Object> map, ParserConfig config) //
13591359
if (value instanceof Number) {
13601360
field.setFloat(object, ((Number) value).floatValue());
13611361
continue;
1362+
} else if (value instanceof String) {
1363+
String strVal = (String) value;
1364+
float floatValue;
1365+
if (strVal.length() <= 10) {
1366+
floatValue = TypeUtils.parseFloat(strVal);
1367+
} else {
1368+
floatValue = Float.parseFloat(strVal);
1369+
}
1370+
1371+
field.setFloat(object, floatValue);
1372+
continue;
13621373
}
13631374
} else if (paramType == double.class) {
13641375
if (value instanceof Number) {
13651376
field.setDouble(object, ((Number) value).doubleValue());
13661377
continue;
13671378
} else if (value instanceof String) {
1368-
double doubleValue = Double.parseDouble((String) value);
1379+
String strVal = (String) value;
1380+
double doubleValue;
1381+
if (strVal.length() <= 10) {
1382+
doubleValue = TypeUtils.parseDouble(strVal);
1383+
} else {
1384+
doubleValue = Double.parseDouble(strVal);
1385+
}
1386+
13691387
field.setDouble(object, doubleValue);
13701388
continue;
13711389
}

src/main/java/com/alibaba/fastjson/util/TypeUtils.java

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2618,6 +2618,132 @@ public static boolean isHibernateInitialized(Object object){
26182618
return true;
26192619
}
26202620

2621+
public static double parseDouble(String str) {
2622+
final int len = str.length();
2623+
if (len > 10) {
2624+
return Double.parseDouble(str);
2625+
}
2626+
2627+
boolean negative = false;
2628+
2629+
long longValue = 0;
2630+
int scale = 0;
2631+
for (int i = 0; i < len; ++i) {
2632+
char ch = str.charAt(i);
2633+
if (ch == '-' && i == 0) {
2634+
negative = true;
2635+
continue;
2636+
}
2637+
2638+
if (ch == '.') {
2639+
if (scale != 0) {
2640+
return Double.parseDouble(str);
2641+
}
2642+
scale = len - i - 1;
2643+
continue;
2644+
}
2645+
2646+
if (ch >= '0' && ch <= '9') {
2647+
int digit = ch - '0';
2648+
longValue = longValue * 10 + digit;
2649+
} else {
2650+
return Double.parseDouble(str);
2651+
}
2652+
}
2653+
2654+
if (negative) {
2655+
longValue = -longValue;
2656+
}
2657+
2658+
switch (scale) {
2659+
case 0:
2660+
return (double) longValue;
2661+
case 1:
2662+
return ((double) longValue) / 10;
2663+
case 2:
2664+
return ((double) longValue) / 100;
2665+
case 3:
2666+
return ((double) longValue) / 1000;
2667+
case 4:
2668+
return ((double) longValue) / 10000;
2669+
case 5:
2670+
return ((double) longValue) / 100000;
2671+
case 6:
2672+
return ((double) longValue) / 1000000;
2673+
case 7:
2674+
return ((double) longValue) / 10000000;
2675+
case 8:
2676+
return ((double) longValue) / 100000000;
2677+
case 9:
2678+
return ((double) longValue) / 1000000000;
2679+
}
2680+
2681+
return Double.parseDouble(str);
2682+
}
2683+
2684+
public static float parseFloat(String str) {
2685+
final int len = str.length();
2686+
if (len >= 10) {
2687+
return Float.parseFloat(str);
2688+
}
2689+
2690+
boolean negative = false;
2691+
2692+
long longValue = 0;
2693+
int scale = 0;
2694+
for (int i = 0; i < len; ++i) {
2695+
char ch = str.charAt(i);
2696+
if (ch == '-' && i == 0) {
2697+
negative = true;
2698+
continue;
2699+
}
2700+
2701+
if (ch == '.') {
2702+
if (scale != 0) {
2703+
return Float.parseFloat(str);
2704+
}
2705+
scale = len - i - 1;
2706+
continue;
2707+
}
2708+
2709+
if (ch >= '0' && ch <= '9') {
2710+
int digit = ch - '0';
2711+
longValue = longValue * 10 + digit;
2712+
} else {
2713+
return Float.parseFloat(str);
2714+
}
2715+
}
2716+
2717+
if (negative) {
2718+
longValue = -longValue;
2719+
}
2720+
2721+
switch (scale) {
2722+
case 0:
2723+
return (float) longValue;
2724+
case 1:
2725+
return ((float) longValue) / 10;
2726+
case 2:
2727+
return ((float) longValue) / 100;
2728+
case 3:
2729+
return ((float) longValue) / 1000;
2730+
case 4:
2731+
return ((float) longValue) / 10000;
2732+
case 5:
2733+
return ((float) longValue) / 100000;
2734+
case 6:
2735+
return ((float) longValue) / 1000000;
2736+
case 7:
2737+
return ((float) longValue) / 10000000;
2738+
case 8:
2739+
return ((float) longValue) / 100000000;
2740+
case 9:
2741+
return ((float) longValue) / 1000000000;
2742+
}
2743+
2744+
return Float.parseFloat(str);
2745+
}
2746+
26212747
public static long fnv1a_64_lower(String key){
26222748
long hashCode = 0xcbf29ce484222325L;
26232749
for(int i = 0; i < key.length(); ++i){
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package com.alibaba.json.bvt.parser;
2+
3+
import com.alibaba.fastjson.util.TypeUtils;
4+
import junit.framework.TestCase;
5+
6+
import java.util.Random;
7+
8+
public class TypeUtils_parseDouble_Test extends TestCase {
9+
public void test_0() throws Exception {
10+
Random r = new Random();
11+
12+
for (int i = 0; i < 1000 * 1000; ++i) {
13+
String str = Float.toString(r.nextFloat());
14+
assertEquals(Double.parseDouble(str), TypeUtils.parseDouble(str));
15+
}
16+
}
17+
18+
public void test_0_d() throws Exception {
19+
Random r = new Random();
20+
21+
for (int i = 0; i < 1000 * 1000; ++i) {
22+
String str = Double.toString(r.nextDouble());
23+
assertEquals(Double.parseDouble(str), TypeUtils.parseDouble(str));
24+
}
25+
}
26+
27+
28+
public void test_1() throws Exception {
29+
Random r = new Random();
30+
31+
for (int i = 0; i < 1000 * 1000; ++i) {
32+
String str = Integer.toString(r.nextInt());
33+
assertEquals(Double.parseDouble(str), TypeUtils.parseDouble(str));
34+
}
35+
}
36+
37+
public void test_2() throws Exception {
38+
Random r = new Random();
39+
40+
for (int i = 0; i < 1000 * 1000; ++i) {
41+
String str = Integer.toString(r.nextInt(1000000000));
42+
assertEquals(Double.parseDouble(str), TypeUtils.parseDouble(str));
43+
}
44+
}
45+
46+
public void test_3() throws Exception {
47+
Random r = new Random();
48+
49+
for (int i = 0; i < 1000 * 1000; ++i) {
50+
String str = Long.toString(r.nextLong());
51+
assertEquals(Double.parseDouble(str), TypeUtils.parseDouble(str));
52+
}
53+
}
54+
55+
public void test_4() throws Exception {
56+
String[] array = new String[] {
57+
"0.34856254",
58+
"1",
59+
"12",
60+
"123",
61+
"1234",
62+
"12345",
63+
"123456",
64+
"1234567",
65+
"12345678",
66+
"123456789",
67+
"1234567890",
68+
".1"
69+
,"1.1"
70+
,"12.1"
71+
, "123.1"
72+
, "1234.1"
73+
, "12345.1"
74+
, "123456.1"
75+
, "1234567.1"
76+
, "12345678.1"
77+
, "0.1"
78+
, "0.12"
79+
, "0.123"
80+
, "0.1234"
81+
, "0.12345"
82+
, "0.123456"
83+
, "0.1234567"
84+
, "0.12345678"
85+
, "0.123456789"
86+
, "0.1234567891"
87+
, "0.12345678901"
88+
, "0.123456789012"
89+
};
90+
91+
for (String str : array) {
92+
assertEquals(Double.parseDouble(str), TypeUtils.parseDouble(str));
93+
}
94+
}
95+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package com.alibaba.json.bvt.parser;
2+
3+
import com.alibaba.fastjson.util.TypeUtils;
4+
import junit.framework.TestCase;
5+
6+
import java.util.Random;
7+
8+
public class TypeUtils_parseFloat_Test extends TestCase {
9+
public void test_0() throws Exception {
10+
Random r = new Random();
11+
12+
for (int i = 0; i < 1000 * 1000; ++i) {
13+
String str = Float.toString(r.nextFloat());
14+
assertEquals(Float.parseFloat(str), TypeUtils.parseFloat(str));
15+
}
16+
}
17+
18+
public void test_1() throws Exception {
19+
Random r = new Random();
20+
21+
for (int i = 0; i < 1000 * 1000; ++i) {
22+
String str = Integer.toString(r.nextInt());
23+
assertEquals(Float.parseFloat(str), TypeUtils.parseFloat(str));
24+
}
25+
}
26+
27+
public void test_2() throws Exception {
28+
Random r = new Random();
29+
30+
for (int i = 0; i < 1000 * 1000; ++i) {
31+
String str = Integer.toString(r.nextInt(1000000000));
32+
assertEquals(Float.parseFloat(str), TypeUtils.parseFloat(str));
33+
}
34+
}
35+
36+
public void test_3() throws Exception {
37+
Random r = new Random();
38+
39+
for (int i = 0; i < 1000 * 1000; ++i) {
40+
String str = Long.toString(r.nextLong());
41+
assertEquals(Float.parseFloat(str), TypeUtils.parseFloat(str));
42+
}
43+
}
44+
45+
public void test_4() throws Exception {
46+
String[] array = new String[] {
47+
"0.34856254",
48+
"1",
49+
"12",
50+
"123",
51+
"1234",
52+
"12345",
53+
"123456",
54+
"1234567",
55+
"12345678",
56+
"123456789",
57+
"1234567890",
58+
".1"
59+
,"1.1"
60+
,"12.1"
61+
, "123.1"
62+
, "1234.1"
63+
, "12345.1"
64+
, "123456.1"
65+
, "1234567.1"
66+
, "12345678.1"
67+
, "0.1"
68+
, "0.12"
69+
, "0.123"
70+
, "0.1234"
71+
, "0.12345"
72+
, "0.123456"
73+
, "0.1234567"
74+
, "0.12345678"
75+
, "0.123456789"
76+
, "0.1234567891"
77+
, "0.12345678901"
78+
, "0.123456789012"
79+
};
80+
81+
for (String str : array) {
82+
assertEquals(Float.parseFloat(str), TypeUtils.parseFloat(str));
83+
}
84+
}
85+
}

0 commit comments

Comments
 (0)