应该 try...catch 进入循环内部还是外部? [英] Should try...catch go inside or outside a loop?
问题描述
我有一个看起来像这样的循环:
I have a loop that looks something like this:
for (int i = 0; i < max; i++) {
String myString = ...;
float myNum = Float.parseFloat(myString);
myFloats[i] = myNum;
}
这是一个方法的主要内容,其唯一目的是返回浮点数数组.如果出现错误,我希望此方法返回 null
,因此我将循环放入 try...catch
块中,如下所示:
This is the main content of a method whose sole purpose is to return the array of floats. I want this method to return null
if there is an error, so I put the loop inside a try...catch
block, like this:
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
块放在循环中,像这样:
But then I also thought of putting the try...catch
block inside the loop, like this:
for (int i = 0; i < max; i++) {
String myString = ...;
try {
float myNum = Float.parseFloat(myString);
} catch (NumberFormatException ex) {
return null;
}
myFloats[i] = myNum;
}
是否有任何理由、性能或其他原因,更喜欢一个?
Is there any reason, performance or otherwise, to prefer one over the other?
共识似乎是将循环放在 try/catch 中更干净,可能放在它自己的方法中.但是,对于哪个更快,仍然存在争议.有人可以对此进行测试并得出统一的答案吗?
The consensus seems to be that it is cleaner to put the loop inside the try/catch, possibly inside its own method. However, there is still debate on which is faster. Can someone test this and come back with a unified answer?
推荐答案
好吧,Jeffrey L Whitledge 说 没有性能差异(截至 1997 年),我去测试了它.我运行了这个小型基准测试:
All right, after Jeffrey L Whitledge said that there was no performance difference (as of 1997), I went and tested it. I ran this small benchmark:
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 检查了生成的字节码,以确保没有内联任何内容.
I checked the resulting bytecode using javap to make sure that nothing got inlined.
结果表明,假设 JIT 优化不重要,Jeffrey 是正确的;在 Java 6、Sun 客户端 VM 上绝对没有性能差异(我无法访问其他版本).整个测试的总时间差在几毫秒的数量级.
The results showed that, assuming insignificant JIT optimizations, Jeffrey is correct; there is absolutely no performance difference on Java 6, Sun client VM (I did not have access to other versions). The total time difference is on the order of a few milliseconds over the entire test.
因此,唯一的考虑是看起来最干净.我发现第二种方式很难看,所以我会坚持第一种方式或 Ray Hayes 的方式.
Therefore, the only consideration is what looks cleanest. I find that the second way is ugly, so I will stick to either the first way or Ray Hayes's way.
这篇关于应该 try...catch 进入循环内部还是外部?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!