fusesource / leveldbjni

A Java Native Interface to LevelDB
BSD 3-Clause "New" or "Revised" License
536 stars 143 forks source link

Memory Pool clarification #32

Closed planck0 closed 11 years ago

planck0 commented 11 years ago

The Readme file mentions a memory pool:

"Using a memory pool to make native memory allocations more efficient"

It is not entirely clear for me how to interpret this and I coudn't find the answers easily in the code either. How does it make memory allocations more efficient? What performance gain can I expect and at what (memory) cost? What is the input unit.. bytes, kilobytes (1024 * 512 = 512K?)? How do I determine its optimal value, should it be equal or somehow relate to block-size, cache-size, or what is the general idea?

chirino commented 11 years ago

Input unit is bytes. Without the memory pool, every Java byte[] for keys and values must be first malloc'ed on the JNI heap. So that's 1 malloc call per key and value followed by a free once the leveldb JNI call is done. With a memory pool, we malloc 1 large memory chunk upfront and copy key and values into it before doing the leveldb JNI call. Once you pop the the pool, then the JNI free of the original malloc occurs. So this reduced the number of JNI calls needed when you do multiple leveldb operations. You can expect about 10% savings. Size it to reduce the number of mallocs/frees that a code section will incur. For example if you memory pool push/pop a area of code is in a loop inserting keys of 512 bytes and values of 512 bytes, and your pool is sized to 10K, then that means an alloc/free will occur about every 10 put calls.

planck0 commented 11 years ago

That's clear, thanks!