バイナリ出力にバッファリングを実装するにはBufferedOutputStreamを用いる。
具体的には、以下のようになる。
import java.io.FileOutputStream; import java.io.BufferedOutputStream; import java.io.OutputStream; class Test { public static void main(String args) throws Exception { byte buf = "Hello world!\n".getBytes(); OutputStream out = new BufferedOutputStream(new FileOutputStream("j_log.txt")); for(int i = 0; i < 10000000; ++i)out.write(buf); } }
ではこれを、まず最適化無しで実行してみよう。
Flat profile of 8.58 secs (548 total ticks): main Interpreted + native Method 32.1% 176 + 0 java.io.BufferedOutputStream.write 27.2% 22 + 127 java.lang.System.arraycopy 13.7% 75 + 0 java.io.FilterOutputStream.write 11.7% 64 + 0 Test.main 9.9% 2 + 52 java.io.FileOutputStream.writeBytes 0.4% 2 + 0 java.io.BufferedOutputStream.flushBuffer 0.2% 1 + 0 java.util.Vector.elementAt 0.2% 1 + 0 java.io.FileOutputStream.write 95.3% 343 + 179 Total interpreted Thread-local ticks: 0.2% 1 Class loader 2.6% 14 Interpreter 1.1% 6 Unknown: running frame 0.9% 5 Unknown: thread_state Global summary of 8.58 seconds: 100.0% 548 Received ticks 0.2% 1 Class loader 2.6% 14 Interpreter 2.0% 11 Unknown code
処理終了までに約9秒しかかからなかった。バッファリング無しの場合の約半分の処理時間である。
バッファリングが無い場合だとjava.io.FileOutputStream.writeBytesに約1000ticksもかかり、それが処理全体の91%を占めていたのに対し、今回のそれはわずかに約50ticks、処理に占める割合も約10%に低下している。
代わりに、java.io.BufferedOutputStream.writeやjava.lang.System.arraycopyといったバッファリングのための処理が大きな部分を占めているが、それらを合わせても、もともとのjava.io.FileOutputStream.writeBytesにかかっていた処理負荷に比べると3分の1程度に過ぎない。
では次は、同じ処理を最適化した場合を見ることにしよう。