Hi,

We have discovered this both in Compact Strings and Indy String Concat
work, but it deserves to be treated separately.

Integer/Long getChars code seems to be very old (Josh Bloch estimated
circa 1994) and written under the assumption no compiler is here to help
us. Fast-forward 20 years, and I would like to suggest a cleanup in
Integer/Long getChars and stringSize:
  http://cr.openjdk.java.net/~shade/8136500/webrev.01/

This cleanup *also* improves performance:
  http://cr.openjdk.java.net/~shade/8136500/notes.txt

While cleaning the code up, the patch does a few things for these reasons:

 * Rewrites Integer.stringSize to the similar loop Long.stringSize is
using. The compiled code shows more efficient code: it does not access
memory anymore, but what's more important, after the loop unrolling we
have the precomputed constants against which we are comparing.

 * Removes the manual strength-reduction of multiplications/divisions to
bit-twiddling: the generated code suggests compiler does it for us. In
fact, manual shifting in current getChar code is a pessimisation!

 * Specializes DigitOnes/Tens for bytes for a Latin1 String cases. This
avoids narrowing conversions in the code: surprisingly, this does affect
performance.

 * Since the weird "65536"-sized bit-twiddling is gone, we can now make
the first loops to cover all values above and equal to 100. This opens
up the way to carefully spell out the code that processes the remaining
two digits -- this does help performance a lot.

 * Avoids Integer.digits lookups, and does the computations in place.
This saves bounds check, and a memory access. (Note that it is a lesser
evil for the DigitOnes/Tens case, where the alternative computation
would involve integer division).

Testing:
  - java/lang, java/util, plus new tests

Thanks,
-Aleksey

Reply via email to