mina-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "이희승 (Trustin Lee) <trus...@gmail.com>
Subject Interesting direct buffer vs heap buffer micro benchmark
Date Sun, 06 Apr 2008 17:52:48 GMT
Hi,

I found direct buffer outperforms heap buffer in most cases in modern
SUN JVM (1.6.0.05 and 1.6.0.10-beta), but I am not sure the result I got
is consistent for more architectures.

The test is very simple; it just reads and writes an integer from/to the
buffer.  What makes this test interesting is that the figures change
dramatically depending on the firstly called test method.  If the
firstly called test is the heap buffer test, heap buffer performs very
well.  However, if the firstly called one is the direct buffer test,
direct buffer outperforms often marginally.  What's obvious though is
that direct buffer outperforms heap buffer in most cases.

If this test result is true for other platforms such as SunOS and
Windows, what could we do?  I know allocating a lot of direct buffers
easily leads to OOM, but I found that I can avoid that problem by
implementing simple JNI functions which simply bypass JVM direct buffer
management and use stdlib malloc/free instead.

I was also able to observe similar test result in JDK 1.5.0.15, but
running the heap test first always resulted in extremely slow direct
buffer performance (3x slowdown), which is also interesting.  Why
hotspot so inconsistent like this?

---- DIRECT FIRST put/getLong() ----
direct: 1237
heap: 2729

---- HEAP FIRST put/getLong() ----
heap: 2830
direct: 1428

---- DIRECT FIRST put/getInt() ----
direct: 2172
heap: 10657

---- HEAP FIRST put/getInt() ----
heap: 5561
direct: 3371

---- DIRECT FIRST put/getShort() ----
direct: 3911
heap: 9517

---- HEAP FIRST put/getShort() ----
heap: 10282
direct: 5133

---- DIRECT FIRST put/get() ----
direct: 6222
heap: 13447

---- HEAP FIRST put/get() ----
heap: 8946
direct: 12235

The test was performed on my laptop (core 2 duo, T9300 2.5GHz) and I'd
like to know what other people got from the following test code.  I
modified get/put methods and the order of the test methods manually.
Probably just running against get/putInt() with two orders will be fine.

---- TEST CODE ----
import java.nio.ByteBuffer;

import org.junit.Test;


public class ByteBufferTest {
    @Test
    public void direct() {
        ByteBuffer buf = ByteBuffer.allocateDirect(2048);
        test("direct", buf);
    }

    @Test
    public void heap() {
        ByteBuffer buf = ByteBuffer.allocate(2048);
        test("heap", buf);
    }

    private void test(String name, ByteBuffer buf) {
        long startTime = System.currentTimeMillis();
        for (int i = 1048576; i > 0; i --) {
            buf.clear();
            while (buf.hasRemaining()) {
                buf.getInt(buf.position());
                buf.putInt((byte) 0);
            }
        }
        long endTime = System.currentTimeMillis();
        System.out.println(name + ": " + (endTime - startTime));
    }
}


-- 
Trustin Lee - Principal Software Engineer, JBoss, Red Hat
--
what we call human nature is actually human habit
--
http://gleamynode.net/


Mime
View raw message