On 11/24/2015 05:50 PM, Ulf wrote:
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];

...but index can be large and overflow byte range. Imagine concatenating into a String with target length > 127 ...

}

        // 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


Reply via email to