Also, you're making a ton of unnecessary calls by using a ByteBuffer to write an int[]. First, take a gander at the source for ByteBuffer (specifically HeapByteBuffer).putInt(int x). It uses a static helper class, Bits, to do the work. But first it has to calculate the offset (two method calls).
Bits makes a single delegating method call (big- or little-endian) which makes eight method calls: four to get the individual bytes of the int and four more to put those bytes into the buffer.
Total method calls, including call to putInt() itself:
13, though the calls to separate the int into bytes are static and could be inlined. That's just ugly. My first recommendation
would have been to use an IntBuffer and skip all that mess, instead using System.arraycopy(), but ...
you can only write ByteBuffers to a FileChannel! Many four-letter words spring to mind, but I'll be nice and leave it at "lame."
So my next suggestion would be to convert the int[] to an intermediary byte[], wrap it with a ByteBuffer, and write that to the FileChannel. After running some tests (see below), this turns out to be faster than the IntBuffer (by about 25%) but still slower than the OOS (more than twice as long).
[ Insert appropriate warning abuot micro-benchmarks here.
]
Here's the code I used to
test.
Here are tests I ran, two of each with 100 iterations writing 786432 pixels.
After making the number of pixels configurable, I ran the tests again using 10240 pixels instead of 786432 with different results:
The average is too small, but notice that the ByteBuffer method is now faster than the ObjectOutputStream, and the latter is more erratic. It's conceivable that using a smaller buffer and writing chunks of the int[] in a loop may prove to be the best method, but I'm too tired to take that up at the moment.