[解決済み】try...catchはループの内側と外側のどちらで行うべきですか?
2022-04-19 15:43:44
質問
次のようなループがあります。
for (int i = 0; i < max; i++) {
String myString = ...;
float myNum = Float.parseFloat(myString);
myFloats[i] = myNum;
}
これは、floatの配列を返すことだけを目的としたメソッドのメインコンテンツです。このメソッドで返したいのは
null
エラーになった場合は、ループを
try...catch
ブロックを、このように
try {
for (int i = 0; i < max; i++) {
String myString = ...;
float myNum = Float.parseFloat(myString);
myFloats[i] = myNum;
}
} catch (NumberFormatException ex) {
return null;
}
しかし、その後に
try...catch
ブロックをループの中に入れて、次のようにします。
for (int i = 0; i < max; i++) {
String myString = ...;
try {
float myNum = Float.parseFloat(myString);
} catch (NumberFormatException ex) {
return null;
}
myFloats[i] = myNum;
}
パフォーマンスやその他の面で、どちらかを選ぶ理由はあるのでしょうか?
編集する ループはtry/catchの中、場合によっては独自のメソッドの中に入れた方がすっきりするというのがコンセンサスになっているようです。しかし、どちらがより速いかについてはまだ議論があります。誰かこれをテストして、統一された答えを持って来ることができますか?
解決方法は?
さて、この後 ジェフリー・L・ウィットレッジのコメント 1997年現在)性能に差はないとのことなので、実際にテストしてみました。こんな小さなベンチマークを走らせてみた。
public class Main {
private static final int NUM_TESTS = 100;
private static int ITERATIONS = 1000000;
// time counters
private static long inTime = 0L;
private static long aroundTime = 0L;
public static void main(String[] args) {
for (int i = 0; i < NUM_TESTS; i++) {
test();
ITERATIONS += 1; // so the tests don't always return the same number
}
System.out.println("Inside loop: " + (inTime/1000000.0) + " ms.");
System.out.println("Around loop: " + (aroundTime/1000000.0) + " ms.");
}
public static void test() {
aroundTime += testAround();
inTime += testIn();
}
public static long testIn() {
long start = System.nanoTime();
Integer i = tryInLoop();
long ret = System.nanoTime() - start;
System.out.println(i); // don't optimize it away
return ret;
}
public static long testAround() {
long start = System.nanoTime();
Integer i = tryAroundLoop();
long ret = System.nanoTime() - start;
System.out.println(i); // don't optimize it away
return ret;
}
public static Integer tryInLoop() {
int count = 0;
for (int i = 0; i < ITERATIONS; i++) {
try {
count = Integer.parseInt(Integer.toString(count)) + 1;
} catch (NumberFormatException ex) {
return null;
}
}
return count;
}
public static Integer tryAroundLoop() {
int count = 0;
try {
for (int i = 0; i < ITERATIONS; i++) {
count = Integer.parseInt(Integer.toString(count)) + 1;
}
return count;
} catch (NumberFormatException ex) {
return null;
}
}
}
出来上がったバイトコードをjavapでチェックし、何もインライン化されていないことを確認しました。
その結果、重要でないJIT最適化を前提とした場合、以下のようになりました。 ジェフリーは正しい は絶対にあります。 Java 6、SunクライアントVMで性能差なし (他のバージョンにはアクセスできませんでした)。テスト全体の時間差は、数ミリ秒のオーダーです。
ですから、一番きれいに見えるのはどれか、ということだけを考えればいいのです。2番目の方法は醜いので、1番目の方法か、あるいは レイ・ヘイズの方法 .
関連
-
スタイルが読み込まれず、ブラウザコンソールでエラーが報告される。リソースはスタイルシートとして解釈されますが、MIMEタイプtext/htmlで転送されます。
-
javaでよく使われる英単語
-
[解決済み] JavaScriptのオブジェクトをループスルーまたは列挙するにはどうすればよいですか?
-
[解決済み] serialVersionUIDとは何ですか、またなぜそれを使用する必要がありますか?
-
[解決済み] ループ内のJavaScriptクロージャ - シンプルな実用例
-
[解決済み] 要素ごとの加算は、結合ループよりも分離ループの方がはるかに高速なのはなぜですか?
-
[解決済み] オブジェクトをメンバーとして、プレーンなJavaScriptオブジェクトをループさせる方法
-
[解決済み] Try-catchは私のコードをスピードアップさせるか?
-
[解決済み] 複数のJava例外を同じcatch節でキャッチすることはできますか?
-
[解決済み】再試行キャッチはどのように実装するのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Java エラー報告 スレッド "main" での例外 java.util.NoSuchElementException
-
エラー java.util.NoSuchElementException
-
myeclipseでコンパイルするとAntエラーが発生する javaの例外が発生しました。
-
eclipse で「アクセス制限: タイプ 'HttpServer' は API ではありません」というプロンプトが表示される。
-
Spring Boot による HTTPS アクセスの設定
-
eclipse の実行時に java 仮想マシンが見つからなかった
-
Javaエラーメッセージがenclosingクラスでない
-
スレッド "main" で例外発生 java.net.BindException: アドレスは既に使用中です。NET_Bind
-
SocketTimeoutExceptionの解決方法です。読み込みがタイムアウトした
-
SocketTimeoutExceptionです。読み込みがタイムアウトしました