Hi,
Am 24.11.2015 um 12:07 schrieb Aleksey Shipilev:
Thanks for reviews, Ivan, John, Sherman and Paul!
I am pushing this change now.
I know, I'm late, but have you ever tried? :
static void getChars(int i, int index, byte[] buf) {
// int q, r; // superfluous
// int charPos = index; // superfluous
boolean negative = i < 0;
// Generate two digits per iteration // q and r are not needed
outside loop
for (int q, i = negative ? i : -i; <= -100; i = q) {
q = i / 100;
byte r = (byte)((q * 100 - i) & 0x7F);
// byte allows the compiler to use byte wide addressing opcodes
// which have smaller footprint and are potentially faster
// .. & 0x7F may additionally save negative bound check
buf[(byte)(--index & 0x7F)] = DigitOnes[r];
buf[(byte)(--index & 0x7F)] = DigitTens[r];
}
// We know there are at most two digits left at this point.
byte q = (byte)i / 10;
buf[(byte)(--index & 0x7F)] = (byte)(q * 10 - i +'0');
// Whatever left is the remaining digit.
if (q < 0) {
buf[(byte)(--index & 0x7F)] = (byte)('0' - q);
}
if (negative) {
buf[(byte)(--index & 0x7F)] = (byte)'-';
}
}
Additionally may try this:
(saves some calculations, but adds array access, only 1 for more frequent i <
10, otherwise 2)
// We know there are at most two digits left at this point.
byte r = (byte)(-i & 0x7F);
buf[(byte)(--index & 0x7F)] = DigitOnes[r];
// Whatever left is the remaining digit.
if (r >= 10) {
buf[(byte)(--index & 0x7F)] = DigitTens[r];
}
if (negative) {
buf[(byte)(--index & 0x7F)] = (byte)'-';
}
2)
The lookup tables DigitTens and DigitOnes are always used together.
Packing them in an one table can save us one array access for the price of
little arithmetic.
static final int[] TwoDigits = {
('0'<<16)+'0', ('0'<<16)+'1', ('0'<<16)+'2', ('0'<<16)+'3',
('0'<<16)+'4',
('0'<<16)+'5', ('0'<<16)+'6', ('0'<<16)+'7', ('0'<<16)+'8',
('0'<<16)+'9',
...
int twoDig = TwoDigits[r];
buf[--charPos] = (byte)twoDig;
buf[--charPos] = (byte)(twoDig >> 16);
...
This could be done faster if using 1 "Unsafe putChar/Short()" instead 2
buf[--charPos] + shift.
... and better use char/short[] to save footprint and the compiler calculating the table offset with
charPos<<1.
Alternatively use byte[] TwoDigits =
useInternalCompactByteArrayOfString("00010203040506070809....")
-Ulf