Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java MappedByteBuffer.get() surprisingly slow

I'm trying to understand if the performance i'm obtaining from the get() method of the MappedByteBuffer class is normal or not. My code is the following:

private byte[] testBuffer = new byte[4194304];
private File sdcardDir, filepath;
private FileInputStream inputStream; 
private FileChannel fileChannel;
private MappedByteBuffer mappedByteBuffer;

// Obtain the root folder of the external storage
sdcardDir = Environment.getExternalStorageDirectory();

// Create the reference to the file to be read
filepath = new File(sdcardDir, "largetest.avi");
inputStream = new FileInputStream(filepath);
fileChannel = inputStream.getChannel();

mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, (4194304));

Log.d("GFXUnpack", "Starting to read");
mappedByteBuffer.position(0);
mappedByteBuffer.get(testBuffer, 0, (4194304));
Log.d("GFXUnpack", "Ended to read");
mappedByteBuffer.rewind();

Since i'm a beginner, and i needed the fastest way to read data from SD card, i looked for documentation and i found that File Mapping is considered, in many cases, the fastest approach to read from a file. But if i run the above code, although the buffer is correctly filled, the performance is so slow (or maybe not ? You decide !!) that i can read those 4194304 bytes in almost 5 seconds, that's less than 1MB per second. I'm using Eclipse directly connected to my Optimus Dual smartphone; the same time is required for the read even if i put the reading operation in a loop (maybe overhead initialization wouldn't take place if multiple reads are performed...Not the case).

This file size-time relation doesn't change if i reduce or make the file larger: 8 megs will be read in almost 9 seconds, 2 megs in 2 seconds, and so on. I've read that even a slow SD card can be read at a speed of at least 5 MB per second... Note that 4194304 is a power of 2 value, since i've read that this would increase performance. Please tell me your opinion: is 1MB per second the actual performance on a modern smartphone, or is there something wrong with my code ? Thank you

like image 291
Logicat Avatar asked Nov 20 '12 12:11

Logicat


2 Answers

Its worth nothing that in the Hotspot JVM, MappedByteBuffer.get() uses an intrinsic rather than a native call. When copying large sections blocks of data it copies multiple bytes at a time e.g. 8 bytes or longer with MMX instructions.

AFAIK, Android doesn't do this, which makes this call much more expensive.

like image 78
Peter Lawrey Avatar answered Oct 24 '22 17:10

Peter Lawrey


I can't see anything wrong with your code. It is probably just the speed of the device and / or the file system implementation. As Tom Hawtin puts it "[m]emory mapped I/O will not make your disks run faster".

like image 1
Stephen C Avatar answered Oct 24 '22 16:10

Stephen C