Javaの文字列出力でバッファリングを行うには、BufferedWriterを使えばよい。
以下のようになる。
import java.io.PrintWriter; import java.io.BufferedWriter; import java.io.FileWriter; class Test { public static void main(String[] args) throws Exception { PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("j_log.txt"))); for(int i = 0; i < 10000000; ++i)out.print("Hello world!\n"); out.close(); } }
まずはこれを最適化無しで実行してみよう。
Flat profile of 130.01 secs (8320 total ticks): main Interpreted + native Method 78.8% 6554 + 0 sun.io.CharToByteDoubleByte.convert 6.4% 536 + 0 sun.io.CharToByteMS932.convSingleByte 5.4% 452 + 0 java.io.BufferedWriter.write 1.8% 20 + 128 java.lang.System.arraycopy 1.7% 142 + 0 java.lang.String.getChars 1.6% 134 + 0 java.io.PrintWriter.write 0.7% 62 + 0 Test.main 0.7% 62 + 0 java.io.PrintWriter.write 0.6% 53 + 0 java.io.PrintWriter.print 0.5% 39 + 0 java.io.BufferedWriter.min 0.3% 29 + 0 java.io.BufferedWriter.ensureOpen 0.3% 0 + 21 java.io.FileOutputStream.writeBytes 0.2% 20 + 0 java.io.PrintWriter.ensureOpen 0.2% 13 + 0 java.lang.String.length 0.0% 4 + 0 sun.nio.cs.StreamEncoder$ConverterSE.implWrite 0.0% 0 + 1 java.security.SecureClassLoader.getProtectionDomain 0.0% 1 + 0 java.io.FileOutputStream.write 0.0% 1 + 0 java.util.jar.Attributes$Name.isValid 0.0% 1 + 0 java.io.BufferedWriter.flushBuffer 0.0% 1 + 0 sun.io.CharToByteConverter.convertAny 0.0% 0 + 1 java.io.WinNTFileSystem.canonicalize 99.5% 8124 + 151 Total interpreted Thread-local ticks: 0.0% 1 Class loader 0.5% 38 Interpreter 0.0% 3 Unknown: running frame 0.0% 3 Unknown: thread_state Global summary of 130.01 seconds: 100.0% 8320 Received ticks 0.0% 1 Class loader 0.5% 38 Interpreter 0.1% 6 Unknown code
やはり、バッファリングしてもそもそも文字コード変換の処理が重過ぎて、あまり効果は無いようだ。
もともと、明示的にバッファリングをしなくても文字コード変換の内部的なバッファの効果があるから、差が顕著にならないという事情もあるのだろう。
次回は、最適化有りのProfileを見てみる。