Skip to content

Commit 3d7185d

Browse files
authored
improve performance with parsing bigints with lots of digits (#826)
1 parent 724964a commit 3d7185d

File tree

3 files changed

+25
-1
lines changed

3 files changed

+25
-1
lines changed

src/main/java/com/fasterxml/jackson/core/io/BigDecimalParser.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public static BigDecimal parse(final char[] chars, final int off, final int len)
3737
return parseBigDecimal(chars, off, len, len / 10);
3838

3939
// 20-Aug-2022, tatu: Although "new BigDecimal(...)" only throws NumberFormatException
40-
// operatons by "parseBigDecimal()" can throw "ArithmeticException", so handle both:
40+
// operations by "parseBigDecimal()" can throw "ArithmeticException", so handle both:
4141
} catch (ArithmeticException | NumberFormatException e) {
4242
String desc = e.getMessage();
4343
// 05-Feb-2021, tatu: Alas, JDK mostly has null message so:

src/main/java/com/fasterxml/jackson/core/io/NumberInput.java

+7
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88

99
public final class NumberInput
1010
{
11+
// numbers with more than these characters are better parsed with BigDecimalParser
12+
// parsing numbers with many digits in Java is slower than O(n)
13+
private final static int LARGE_INT_SIZE = 1250;
14+
1115
/**
1216
* Formerly used constant for a value that was problematic on certain
1317
* pre-1.8 JDKs.
@@ -395,6 +399,9 @@ public static BigDecimal parseBigDecimal(char[] ch) throws NumberFormatException
395399
* @since v2.14
396400
*/
397401
public static BigInteger parseBigInteger(String s) throws NumberFormatException {
402+
if (s.length() > LARGE_INT_SIZE) {
403+
return BigDecimalParser.parse(s).toBigInteger();
404+
}
398405
return new BigInteger(s);
399406
}
400407
}

src/test/java/com/fasterxml/jackson/core/io/TestNumberInput.java

+17
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.fasterxml.jackson.core.io;
22

3+
import java.math.BigInteger;
4+
35
public class TestNumberInput
46
extends com.fasterxml.jackson.core.BaseTest
57
{
@@ -24,5 +26,20 @@ public void testParseFloat()
2426
assertEquals("1.4E-45", Float.toString(NumberInput.parseFloat(exampleFloat2)));
2527
assertEquals("1.4E-45", Float.toString(NumberInput.parseFloat(exampleFloat2, true)));
2628
}
29+
30+
public void testParseLongBigInteger()
31+
{
32+
StringBuilder stringBuilder = new StringBuilder();
33+
for (int i = 0; i < 1000; i++) {
34+
stringBuilder.append(7);
35+
}
36+
String test1000 = stringBuilder.toString();
37+
assertEquals(new BigInteger(test1000), NumberInput.parseBigInteger(test1000));
38+
for (int i = 0; i < 1000; i++) {
39+
stringBuilder.append(7);
40+
}
41+
String test2000 = stringBuilder.toString();
42+
assertEquals(new BigInteger(test2000), NumberInput.parseBigInteger(test2000));
43+
}
2744
}
2845

0 commit comments

Comments
 (0)