Search code examples
javaandroidperformancenio

how to improve MappedByteBuffer get performance for my use case?


I have several large double and long arrays of 100k values each that needs to be accessed for computation at a given time, even with largeHeap requested the Android OS doesnt give me enough memory and i keep getting outofmemory exceptions in most of tested devices. So i went researching for ways to overcome this, and according to an answer i got from Waldheinz in my previous question i implemented an array that is based on a file, using RandomAccessMemory to get a channel to it, then map it using MappedByteBuffer as suggested, and use the MappedByteBuffer asLongBuffer or asDoubleBuffer. this works perfect, i 100% eliminated the outofmemory exceptions. but the performance is very poor. i get lot of calls to get(some index) that takes about 5-15 miliseconds each and therefore user exprience is ruined

some usefull information :

  1. i am using binary search on the arrays to find a start and end indices and then i have a linear loop from start to end
  2. I added a print command for any get() calls that takes more then 5 mili seconds to finish (printing out time it took,requested index and the last requested index), seems like all of the binary search get requests were printed, and few of the linear requests were too.

Any suggestions on how to make it go faster?


Solution

  • Approach 1

    Index your data - add pointers for quick searching

    • Split your sorted data into 1000 buckets 100 values each
    • Maintain an index referencing each bucket's start and end
    • The algorithm is to first find your bucket in this memory index (even a loop is fine for this) and then to jump to this bucket in a memory mapped file

    This will result into a single jump over a file (a single bucket to find) and an iteration on 100 elements max.

    Approach 2

    Utilize a lightweight embedded database. I.e. MapDB supports Android.