应该尝试......赶上一个循环内外? [英] 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;
}
但是我还想过把试试。 ..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?
推荐答案
好吧,在杰弗里·L·惠特利奇说没有性能差异(截至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客户端虚拟机上绝对没有性能差异(我没有访问其他版本)。总时间差在整个测试中大约为几毫秒。
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.
这篇关于应该尝试......赶上一个循环内外?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!