前回は、例外の検出方法でif文とtry〜catch文を比較したけど、今回はループの中と外。
確かに、try〜catchのブロックでスタックの動作があるだろうから、全く差がないってことはないかも?とは思ったものの、下記のページであまりにも差があったので。
Java講座 > 5.3. try-catch ブロックはループ外に置く
で、ループ繰り返し回数が1000回の場合、188[ms]かかってたのが1[ms]未満になるってので再度調べてみた。
検証コード
public class TryCatchTest { private static int LOOP = 10000; private static String EXIST_FILE = "C:\\hoge.txt"; // 存在するファイル private static String NOT_EXIST_FILE = "C:\\fuga.txt"; // 存在しないファイル public static void main(String[] args) { new TryCatchTest().test(); } public void test() { long s; System.out.println("■存在するファイル"); s = System.currentTimeMillis(); internal(LOOP, EXIST_FILE); System.out.println(" 1)ループ中 : " + (System.currentTimeMillis() - s) + "[ms]"); s = System.currentTimeMillis(); external(LOOP, EXIST_FILE); System.out.println(" 2)ループ外 : " + (System.currentTimeMillis() - s) + "[ms]"); System.out.println("■存在しないファイル"); s = System.currentTimeMillis(); internal(LOOP, NOT_EXIST_FILE); System.out.println(" 3)ループ中 : " + (System.currentTimeMillis() - s) + "[ms]"); s = System.currentTimeMillis(); external(LOOP, NOT_EXIST_FILE); System.out.println(" 4)ループ外 : " + (System.currentTimeMillis() - s) + "[ms]"); } public void internal(int loop, String filename) { for (int i = 0; i < loop ; i++) { try { FileInputStream fis = new FileInputStream(filename); } catch (FileNotFoundException e) { } } } public void external(int loop, String filename) { try { for (int i = 0 ; i < loop ; i++) { FileInputStream fis = new FileInputStream(filename); } } catch (FileNotFoundException e) { } } }
実行結果(1万回)
お!「1)ループ中」の方が時間かかってる。やっぱスタックの処理分不利なのか?
でも、「2)ループ外 」って1[ms]未満じゃねぇよ…
■存在するファイル 1)ループ中 : 184[ms] 2)ループ外 : 125[ms] ■存在しないファイル 3)ループ中 : 530[ms] 4)ループ外 : 0[ms]
そもそもサンプルのコードって、「c:\hoge\foo\bar.dat」が存在しないから、『After』のコードでは、Exceptionがthrowされてループから抜けてる(1回しかループしてない)んじゃないの???
とか。
実行結果(100万回)
大体こんな数字なんだけど、なぜか殆ど「1)ループ中 <2)ループ外」なんだよなー
■存在するファイル 1)ループ中 : 12229[ms] 2)ループ外 : 12288[ms] ■存在しないファイル 3)ループ中 : 25325[ms] 4)ループ外 : 0[ms]
結論
ということで、例外でコストを意識しないといけないのは例外の生成であって、やっぱtry〜catchのコストは無視していいんだよ。