Skytopia > Projects > Technology/science articles > Java IO speed comparison

Java IO speed comparison

For those of you looking for high-speed reading and writing of bytes in Java - look no further. Covered on this page are speed tests for eight types of IO commands: FileInputStream, ByteArrayInputStream, MappedByteBuffer, ByteBuffer, DataBufferByte, RandomAccessFile, BufferedInputStream, and simply using a byte[] array. Unless I'm mistaken, only 3 of them are actually needed for most everyday use. Which three are they though? Well find out and see...

To test the speeds, I used JDK 1.4.2 running on a Pentium M clocked at 1.3GHz. The actual reading and writing was performed on a 30 megabyte file, and I used the currentTimeMillis command to record the times (accurate to 1/100th of a second). If possible, I also tested random access speeds as well as serial. Common sense would dictate that speed is traded off for the ability to write/read a piece of memory at random address bytes, but I strangely found this not to be the case.

If you want to examine the java code for yourself, here you go.



Type Access
from
initilize read
(0...n)
write RA read RA write
8: FileInputStream HD 0 72 s
read()
--- --- ---
7: ByteArrayInputStream RAM0.21 s 0.7 s
read()
--- --- ---
6: MappedByteBuffer RAM 0.004 s 0.68 s
get()
--- 3.4 s ---
5: ByteBuffer RAM 0.35 s 0.17 s
get(n)
0.28 s
put(n,(byte)50)
2.4 s
get(rnd)
4.8 s
put(rnd,(byte)50)
4: DataBufferByte RAM 0.05 s 0.16 s
getElem(n)
0.24 s
setElem(n,50)
2.5 s
getElem(rnd)
4.4 s
setElem(rnd,50)
3: RandomAccessFileHD 0 s 80 s
read()
110 s
write(50)
125 s
seek(rnd); read()
160 s
seek(rnd); write(50)
2: BufferedInputStream mostly
RAM
0 s 0.95 s
read()
--- --- ---
1: byte[] RAM 0.25 s 0.01-0.05 s
v[n]
0.01-0.15 s
v[rnd]
2.2 s
v[n]=(byte)50
4.4 s
v[rnd]=(byte)50



Well, how about that! And to think you've (probably) been using the BufferedInputStream class all this time. The byte[] method is the winning benchmark, and it turns out that an array of bytes is in general the most efficient at reading and writing. The only 'downside' is the slightly longer initilization time, but once it's in RAM, then it's the bees knees. You get superfast reads, writes, and random access to boot. Interestingly, the speed of random reads and writes, compared to serial, is proportional to how 'far away' the next byte to be accessed is.

Testing speeds at low level

Because of the superfast speed from byte[], it was very difficult to time properly. Another variable access or even the loop itself can dramatically affect the time. I had to take off 100 milliseconds, as a loop without any body eats up time over 30 million repetitions. Well most of the time... I found out that changing some code above an empty loop (that had nothing to do with it) affected the empty loop's execution time in a psuedo random manner!

I urge caution to those who want to speed-test Java functions as weird stuff like this can happen.
Of course, although the FileInputStream class is the 'worst' in the chart due to its atrocious reading speeds, you'll actually need it anyway to load a file in the first place. A RandomAccessFile file although, again very slow, is useful for reading and writing directly from the hard drive (say if you lack RAM memory). And if you're prepare to forego the writing potential of RandomAccessFile, then the good old fashioned BufferedInputStream class takes up very little memory. I believe that for everyday use, only RandomAccessFile, BufferedInputStream, and byte[] are needed. The other classes are nearly redundant.

So if you want to use the simple but effective byte[] storage, how do you go about converting a file to an array of bytes from a FileInputStream? Simple:
File file = new File("blahblah");
FileInputStream fis = new FileInputStream(file);
byte[] b = new byte[(int)file.length()];
fis.read(b);
The "fis.read(b)" code simply puts the contents of the file into the massive byte array - b.


Links:

  • Tweak your IO performance for faster runtime
  • Java New Input/Output




    All pictures and text on this page are copyright 2005 onwards Daniel White.
    If you wish to duplicate any of the information from this page, please contact me for permission.