System.out.println()とprint()について

Javaのコードその1

System.out.println("hogehoge");

Javaのコードその2

System.out.print("hogehoge\n");

今回のお題は、上記コード「その1」と「その2」は速度的に違いがあるのか、についてです。機能的には全く同じ2つのコードですが、スピードはどうなんでしょうね。

straceというLinuxシステムコールをトレースするためのツールをかましJVMを走らせて見たところ、printlnとprintには以下のような違いがあることが分かりました。

println("hogehoge")の場合に呼び出されるシステムコール

write(1, "Hello Java World!", 17)
write(1, "\n", 1)

一方、print("hogehoge\n")の場合に呼び出されるシステムコール

write(1, "Hello Java World!\n", 18)

はい、この通り、writeシステムコールを呼び出す回数にそのまんま直結しちゃってます。

ちなみに、これはSun JDK 5.0 Update6での結果です。他のJVMでは調べてませんのであしからず。

それぞれ10万回、100万回呼び出すJavaプログラムを作って時間を計測してみました。

println("Hello Java World!")を10万回。

real    0m1.165s
user    0m0.353s
sys     0m0.798s

print("Hello Java World!\n")を10万回。

real    0m0.924s
user    0m0.251s
sys     0m0.630s

println("Hello Java World!")を100万回。

real    0m9.676s
user    0m3.527s
sys     0m6.027s

print("Hello Java World!\n")を100万回。

real    0m5.145s
user    0m1.907s
sys     0m3.202s

という結果になりました。

起動時にJVMJavaのシステムライブラリ(JARファイル)を読み込むオーバーヘッドにより、10万回だとそれほど大きな差は出ていませんが、100万回繰り返した場合には2倍近い差がでていますね。

まあ繰り返し回数を増やすほど、print/printlnそのものによる差が顕著にでてくるわけですから、当然といえば当然です。

こんなことが分かったからといって、だからまあ何だと言うわけではないですが、Javaも他の言語も基本的にはOSのシステムコールに依存しているわけで、そしてまたシステムコールというのがただの関数呼び出しに比べるとかなり重い処理ですから、高速プログラムを書こうと思う場合にはこの辺の知識も活かした方がよいのかなとか、思ったわけです。

そんなわけでおしまいおしまい。