Please review a potential fix of [1].

BigInteger.toString(int radix) for instances with more than 20 ints in the 
magnitude array works by recursively decomposing the BigInteger into smaller 
BigIntegers which have no more than 20 ints in their magnitude array and then 
uses the internal method smallToString() to convert the smaller BigIntegers 
into Strings. Internally smallToString() uses a StringBuilder to concatenate 
component digits and then returns the String created by 
StringBuilder.toString(). The various strings returned by smallToString() are 
themselves concatenated in another StringBuilder and the value eventually 
returned by this StringBuilder’s toString() method is the final result. So all 
in at least four times the memory needed for the character content of the final 
result is allocated. Also at least the StringBuilder which contains the final 
result is likely resizing itself to ensure sufficient capacity and performing a 
copy each time it resizes.

The proposed change [2] uses one single StringBuilder with capacity sufficient 
to contain the final result. The memory needed is therefore reduced to twice 
that needed for the character content of the final result. Also, intermediate 
StringBuilder self-resizings are eliminated altogether as the StringBuilder has 
sufficient capacity to contain the final result.

This method is covered in testing by the existing stringConv() method of 
BigIntegerTest. Numerous other tests were also run with larger values using the 
same methodology: create a BigInteger x, get the result s = x.toString(radix) 
for each radix, create a new value BigInteger y = BigInteger(s,radix), verify 
that y.equals(x) is true.

Thanks,

Brian
 
[1] https://bugs.openjdk.java.net/browse/JDK-8229845 
<https://bugs.openjdk.java.net/browse/JDK-8229845>
[2] http://cr.openjdk.java.net/~bpb/8229845/webrev.00/

Reply via email to