Hi Staffan,

You're right. I thought ByteBuffer was more optimal in this respect.

Regards, Peter

On 10/17/2014 06:47 PM, Staffan Friberg wrote:
Hi Peter,

Thanks for reviewing.

I have switched to the Integer methods. Was looking through that API but I was too stuck with the reflect and swap names so I missed the reverse methods... :)

As Vitaly noted in his email the wrapped case runs much slower. Going through the generated code it looks like the getInt method actually read four bytes and then builds and int from them, unless we have some intrinsic replacing that code.

Bits.java
    static int getIntL(long a) {
        return makeInt(_get(a + 3),
                       _get(a + 2),
                       _get(a + 1),
                       _get(a    ));
    }

    static private int makeInt(byte b3, byte b2, byte b1, byte b0) {
        return (((b3       ) << 24) |
                ((b2 & 0xff) << 16) |
                ((b1 & 0xff) <<  8) |
                ((b0 & 0xff)      ));
    }

It looks like the same holds true for DirectByteBuffers unless you are on x86 which supports unaligned reads. So I think aligning and using Unsafe is the best option here for performance.

DirectByteBuffer.java
    private int getInt(long a) {
        if (unaligned) {
            int x = unsafe.getInt(a);
            return (nativeByteOrder ? x : Bits.swap(x));
        }
        return Bits.getInt(a, bigEndian);
    }

Bits.java
    static boolean unaligned() {
        if (unalignedKnown)
            return unaligned;
        String arch = AccessController.doPrivileged(
            new sun.security.action.GetPropertyAction("os.arch"));
        unaligned = arch.equals("i386") || arch.equals("x86")
            || arch.equals("amd64") || arch.equals("x86_64");
        unalignedKnown = true;
        return unaligned;
    }

Regards,
Staffan

Reply via email to