Stupid performance trick in Java

ByteBuffer has a compact() method which is useful for re-using a buffer if it is not full consumed. However, in the likely case it is consumed, it can perform surprising badly.

while (in.read(buf) >= 0 || buf.position != 0) {
     buf.flip();
     out.write(buf);
     buf.compact();    // In case of partial write
}

In my application, the throughput increased by 6% by replacing compact() with this method.

public static void compact(ByteBuffer bb) {
    if (bb.remaining() == 0)
        bb.clear();
    else
        bb.compact();
}

Note: this is not the increase in a micro-benchmark, but across the entire application!

Your Mileage May Vary of course

Comments

  1. I wonder whether your app does anything else (i.e. real IO). Tested on Windows with -server JVM: https://gist.github.com/1486476

    ReplyDelete
  2. What may not have been clear is that the ByteBuffer is typically empty. In this situation, calling clear() instead of compact() it makes a big difference.

    BTW: Using direct memory also appears to make more of a difference.

    private static long test(int[] writes, Compactor cn) {
    final ByteBuffer b = ByteBuffer.allocateDirect(PAGE);
    long written = 0;

    for (int i = 0; i < writes.length; ++i) {
    b.limit(i % PAGE);
    b.position(i % PAGE);
    cn.compact(b);
    }
    return written;
    }

    prints

    Run: 2

    norm : 906624000ns
    opt : 307983000ns
    Factor norm/opt : 2.944

    ReplyDelete

Post a Comment

Popular posts from this blog

Why You Should Tune Code Before Your Garbage Collector

Asking multiple AI to optimise the same code

Which Doc Format is Best for AI Specifications?