Hi, I don't work on the core classes, so can't help you directly. However, the results here seem pretty clear -- use the fast ones, not the slow ones. For the most part these seem kind-of logical, as it will be slower to copy the array yourself, and even slower to call a function for each byte in the array.
The one that is most obviously slow is the last, where clearly there is some temporary being created for each byte read... but also clearly you wouldn't want to do that approach anyway, since you are not doing any buffering of the raw file as far as I can see. Typically for efficient reading, you would just allocate a byte array up-front and read directly into that. In general code gets optimized when someone is using it and needs to have it go faster. The quickest way to get optimizations in when you run into slow APIs is to contribute patches, though you can certainly file a bug and at some point someone may look into it depending on its priority relative to other things. (With so many possible ways to read files, many of which are reasonably efficient, I don't think it would end up a high priority to optimize your last or few last cases.) On Sat, May 9, 2009 at 9:37 PM, beekeeper <[email protected]> wrote: > > I've been beating my head against the wall trying to figure out which > file I/O techniques work at speeds comparable to their Java SDK > counterparts, and which don't. I've run benchmarks which indicate, > for example, that a batch operation on a memory mapped ByteBuffer runs > at 1/5 the speed of byte-at-a-time operations on an array-backed > ByteBuffer. Byte-at-a-time I/O on random access files is more than > 100 times slower than other techniques. I've included my benchmark > method and its output (as run on a 2.8MB file on a HTC G1 with Android > 1.1) below. > > My primary questions are: > 1) Has anybody else worked through various I/O techniques under > Android and figured out which are usable and which are too inefficient > to bother with? > 2) Can I expect these libraries to be significantly more efficient in > Android 1.5? > > Question (2) is the really important one. I'll rewrite my apps for > efficiency if I have to, but if the issue is going to be rendered moot > in a matter of weeks, I'd rather not go to quite as much trouble. > > -Beekeeper > > --- > > public void testReading(final RandomAccessFile in) throws > IOException { > // Allocate files and objects outside of timing loops > final FileChannel channel = in.getChannel(); > final int fileSize = (int)channel.size(); > final byte[] testBytes = new byte[fileSize]; > final ByteBuffer buff = ByteBuffer.allocate(fileSize); > final byte[] buffArray = buff.array(); > final int buffBase = buff.arrayOffset(); > > // Read from channel into buffer, and batch read from buffer to > byte array > long time1 = System.currentTimeMillis(); > channel.position(0); > channel.read(buff); > buff.flip(); > buff.get(testBytes); > long time2 = System.currentTimeMillis(); > System.out.println("Fast load: " + (time2 - time1) + "ms"); > > > // Read from channel into buffer, and batch copy from underlying > array > time1 = System.currentTimeMillis(); > channel.position(0); > channel.read(buff); > buff.flip(); > System.arraycopy(buffArray, buffBase, testBytes, 0, > testBytes.length); > time2 = System.currentTimeMillis(); > System.out.println("Another fast load: " + (time2 - time1) + > "ms"); > > // Read from channel into buffer, and get bytes one-by-one from > underlying array > time1 = System.currentTimeMillis(); > channel.position(0); > channel.read(buff); > buff.flip(); > for (int i = 0, j = buffBase, ni = testBytes.length; i < ni; i++, j > ++) > testBytes[i] = buffArray[j]; > time2 = System.currentTimeMillis(); > System.out.println("Fastish load: " + (time2 - time1) + "ms"); > > // Read from channel into buffer, and get bytes one-by-one > time1 = System.currentTimeMillis(); > channel.position(0); > channel.read(buff); > buff.flip(); > for (int i = 0, ni = testBytes.length; i < ni; i++) > testBytes[i] = buff.get(); > buff.flip(); > time2 = System.currentTimeMillis(); > System.out.println("Medium load: " + (time2 - time1) + "ms"); > > // Memory map buffer, and batch read from buffer to byte array > time1 = System.currentTimeMillis(); > final MappedByteBuffer buff2 = channel.map(MapMode.READ_WRITE, 0, > fileSize); > buff2.get(testBytes); > buff2.flip(); > time2 = System.currentTimeMillis(); > System.out.println("Slow load: " + (time2 - time1) + "ms"); > > // Read bytes one-by-one, directly from file > time1 = System.currentTimeMillis(); > in.seek(0); > for (int i = 0, ni = testBytes.length; i < ni; i++) > testBytes[i] = (byte)in.read(); > time2 = System.currentTimeMillis(); > System.out.println("Incredibly slow load: " + (time2 - time1) + > "ms"); > } > > --- > > I/System.out(12168): Fast load: 83ms > I/System.out(12168): Another fast load: 23ms > I/System.out(12168): Fastish load: 1497ms > I/System.out(12168): Medium load: 5507ms > I/System.out(12168): Slow load: 32165ms > D/dalvikvm(12168): GC freed 87347 objects / 2097056 bytes in 242ms > D/dalvikvm(12168): GC freed 87367 objects / 2097152 bytes in 250ms > D/dalvikvm(12168): GC freed 87367 objects / 2097144 bytes in 242ms > D/dalvikvm(12168): GC freed 87367 objects / 2097152 bytes in 249ms > D/dalvikvm(12168): GC freed 87367 objects / 2097144 bytes in 247ms > D/dalvikvm(12168): GC freed 87367 objects / 2097152 bytes in 249ms > D/dalvikvm(12168): GC freed 87367 objects / 2097144 bytes in 242ms > D/dalvikvm(12168): GC freed 87367 objects / 2097152 bytes in 252ms > D/dalvikvm(12168): GC freed 87367 objects / 2097144 bytes in 243ms > D/dalvikvm(12168): GC freed 87367 objects / 2097152 bytes in 249ms > D/dalvikvm(12168): GC freed 87367 objects / 2097144 bytes in 243ms > D/dalvikvm(12168): GC freed 87367 objects / 2097152 bytes in 249ms > D/dalvikvm(12168): GC freed 87367 objects / 2097144 bytes in 243ms > D/dalvikvm(12168): GC freed 87367 objects / 2097152 bytes in 249ms > D/dalvikvm(12168): GC freed 87367 objects / 2097144 bytes in 242ms > D/dalvikvm(12168): GC freed 87367 objects / 2097152 bytes in 250ms > D/dalvikvm(12168): GC freed 87367 objects / 2097144 bytes in 243ms > D/dalvikvm(12168): GC freed 87367 objects / 2097152 bytes in 249ms > D/dalvikvm(12168): GC freed 87367 objects / 2097144 bytes in 245ms > D/dalvikvm(12168): GC freed 87367 objects / 2097152 bytes in 251ms > D/dalvikvm(12168): GC freed 87367 objects / 2097144 bytes in 242ms > D/dalvikvm(12168): GC freed 87367 objects / 2097152 bytes in 250ms > D/dalvikvm(12168): GC freed 87367 objects / 2097144 bytes in 242ms > D/dalvikvm(12168): GC freed 87367 objects / 2097152 bytes in 249ms > D/dalvikvm(12168): GC freed 87367 objects / 2097144 bytes in 244ms > D/dalvikvm(12168): GC freed 87367 objects / 2097152 bytes in 249ms > D/dalvikvm(12168): GC freed 87367 objects / 2097144 bytes in 243ms > D/dalvikvm(12168): GC freed 87367 objects / 2097152 bytes in 250ms > D/dalvikvm(12168): GC freed 87367 objects / 2097144 bytes in 243ms > D/dalvikvm(12168): GC freed 87367 objects / 2097152 bytes in 251ms > I/System.out(12168): Incredibly slow load: 446546ms > > > > > > -- Dianne Hackborn Android framework engineer [email protected] Note: please don't send private questions to me, as I don't have time to provide private support, and so won't reply to such e-mails. All such questions should be posted on public forums, where I and others can see and answer them. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Android Developers" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/android-developers?hl=en -~----------~----~----~----~------~----~------~--~---

