文系プログラマーのプログラミング備忘録

Java、競プロ、数学などについて書いてます

[Java] 標準入力・標準出力の速度比較 [競技プログラミング]

以下の記事にもある通り、Java の Scanner は処理速度が遅いです。


qiita.com


AtCoder にある Java のサンプルコードでは Scanner が使われていますし、Scanner を使ったら TLE してしまった……といった問題はまずないかと思いますが、いざというときのためにも、Scanner より高速な入力方法、そして System.out.println() よりも高速な出力方法を覚えておきたいと思い、調べてみることにしました。


本記事では、Javaにおける入出力の方法を比較し、どの方法が優れているのかを検証します。


標準入力

int型整数を以下の3つの方法で取得し、実行速度を比較します。


・Scanner.nextInt()
・Integer.parseInt(Scanner.next())
・FastScanner


FastScanner は、本記事の最初に紹介したサイト内にあるものを参考にしました。


検証には以下の問題を使います。int型整数を最大で100000回取得する必要があり、速度差を比較するには十分な数だと判断しました。


yukicoder.me


検証結果

・Scanner.nextInt()
[478ms] https://yukicoder.me/submissions/316544


・Integer.parseInt(Scanner.next())
[385ms] https://yukicoder.me/submissions/320340


・FastScanner
[166ms] https://yukicoder.me/submissions/320341


思っていたより差がない……ですね。とくに、Integer.parseInt(Scanner.next()) はもっと速いのかと思ってました。しかし、Java だと入力が1個でも実行速度が100msを超えますから、実際は Scanner.nextInt() より FastScanner のほうが5~6倍くらい速いんでしょう。



標準出力

文字列を以下の3つの方法で出力し、実行速度を比較します。


・System.out.println()
・System.out.println(String Builder) ※1行に圧縮
・PrintWriter


System.out.println() と String Builder での1行出力については以前も記事にしましたが、今回はそれに加えて PrintWriter も比較してみることにしました。


検証には以下の問題を使います。この問題では、最大で100000個の文字列を出力する必要があります。


atcoder.jp


検証結果

・System.out.println()
[656ms] Submission #4229884 - CODE FESTIVAL 2016 qual B


・System.out.println(StringBuilder)
[215ms] Submission #4229924 - CODE FESTIVAL 2016 qual B


・PrintWriter
[211ms] Submission #4418362 - CODE FESTIVAL 2016 qual B


PrintWriter と String Builder の差がほとんどというか、全くありませんね。
では、実行速度ではなくメモリの消費量はどうでしょうか。下2つを比較してみます。


・System.out.println(StringBuilder)
 → 29092 KB
・PrintWriter
 → 25400 KB


メモリの使用量はそれなりに差がありますね。
記述量の点からいっても、Java で高速に出力したい場合は PrintWriter を使うべきでしょう。



まとめ

標準入力については FastScanner が最も速いですが、コードがどうしても長くなってしまうので、スマートな解答を提出したいという方は Scanner や Integer.parseInt(), Long.parseLong() で問題ないと思います。


標準出力については PrintWriter を使うのがオススメです。かくいう私も System.out.println() しか使っていなかった身ですが、これからは PrintWriter を使おうと思います。