libcj java.nio.DirectBuffer is slow (no inlining)

P.O. Gaillard pierre-olivier.gaillard@fr.thalesgroup.com
Wed Jun 7 12:48:00 GMT 2006


Florian Weimer wrote:
> * P. O. Gaillard:
> 
> 
>>I am using the gcj 4.1 that came with Fedora Core 5 and the NIO
>>buffers are quite slow. From what I see with Oprofile, I would say
>>that this is because the code is not inlined.
> 
> 
> Most of the java.nio buffer methods are non-final, so inlining can
> only happen after devirtualization. This is hard to do at compile
> time.
> 
> Are you sure the problem is lack of inlining?  There used to be
> problems with inefficient implementations of the array-based get/put
> methods.  Maybe you could post an excerpt of the profiles, so that we
> can see what's going on.
> 
Indeed, I tried to use the array-based get/put. The get + some custom endianness 
handling proved faster than the provided getInt.

Also, using a buffer from allocate rather than one provided by allocateDirect is 
much faster (a program running in 14secs with direct buffers went down to 11sec 
with regular buffers). This seems logical when looking at the code since direct 
buffer add another level of non-inlined method calls.

The top of one of my profiles are as follows (using mostly getInt, 
allocateDirect buffer) :

CPU: P4 / Xeon, speed 2794.32 MHz (estimated)
Counted GLOBAL_POWER_EVENTS events (time during which processor is not stopped) 
with a unit mask of 0x01 (mandatory) count 100000
samples  %        image name               app name                 symbol name
56406     8.9007  no-vmlinux               no-vmlinux               (no symbols)
42008     6.6287  libgcj.so.7.0.0          libgcj.so.7.0.0 
__i686.get_pc_thunk.bx
36104     5.6971  libgcj.so.7.0.0          libgcj.so.7.0.0 
java::nio::Buffer::hasRemaining()
30887     4.8739  libgcj.so.7.0.0          libgcj.so.7.0.0 
java::nio::Buffer::position(int)
28672     4.5244  libgcj.so.7.0.0          libgcj.so.7.0.0 
java::nio::DirectByteBufferImpl::put(char)
28615     4.5154  GenesisMark              GenesisMark 
com::thalesgroup::tnf::LRC::IO::LRCBitBuffer::adjustOffset(int)
21232     3.3503  libfb.so                 libfb.so                 (no symbols)
21222     3.3488  libgcj.so.7.0.0          libgcj.so.7.0.0 
java::nio::DirectByteBufferImpl::get()
21154     3.3380  libgcj.so.7.0.0          libgcj.so.7.0.0          .plt
18658     2.9442  CustomProg              CustomProg 
reference::res_msg_block::TargetRecordType::encode(com::thalesgroup::tnf::LRC::IO::LRCBitBuffer*)
16852     2.6592  CustomProg              CustomProg 
reference::res_msg_block::TargetRecordType::decode(com::thalesgroup::tnf::LRC::IO::LRCBitBuffer*)
15996     2.5241  libgcj.so.7.0.0          libgcj.so.7.0.0          _Jv_CheckCast
15167     2.3933  libgcj.so.7.0.0          libgcj.so.7.0.0          _Jv_InitClass

So it seems that hasRemaining and position are not inlined which seems 
unfortunate since they are trivial methods. The buffer seems to do a lot of 
bound checking.

    thank you for your attention and for your help,

    P.O. Gaillard





More information about the Java mailing list