当前位置: 首页 > 面试题库 >

应该尝试…捕捉到循环内还是循环外?

丁茂
2023-03-14
问题内容

我有一个看起来像这样的循环:

for (int i = 0; i < max; i++) {
    String myString = ...;
    float myNum = Float.parseFloat(myString);
    myFloats[i] = myNum;
}

这是方法的主要内容,其唯一目的是返回浮点数数组。我希望此方法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中(可能在其自己的方法中)更干净。但是,仍然存在关于哪个更快的争论。有人可以测试一下并返回统一答案吗?


问题答案:

好的,在Jeffrey L Whitledge说没有性能差异(截至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优化Jeffrey是正确的Java 6,Sun客户端VM上 绝对 没有性能差异
(我无法访问其他版本)。在整个测试中,总的时间差约为几毫秒。

因此,唯一的考虑就是看起来最干净的东西。我发现第二种方法很难看,所以我会坚持第一种方法或Ray
Hayes的方法



 类似资料:
  • 问题内容: 下面的代码询问用户他/她想要多少个赛车手。 如果在代码中输入数字,则代码会跳出循环,并且程序的其余部分可以正常运行;但是,当我输入诸如“ awredsf”之类的内容时,它应该捕获该异常,并且确实如此。它没有连续提示用户,而是连续循环,这对我来说没有意义。 连续循环时,程序打印如下: 多少赛车手应该参加比赛?多少赛车手应该参加比赛?多少赛车手应该参加比赛?多少赛车手应该参加比赛?多少赛车

  • 我的程序接受整数输入,然后是一个更大的整数输入,然后是一个字符串。 “输入一个数字:” “请输入一个更大的数字:” “输入字符串:” 我试图使用try/catch来捕获输入字符串而不是整数的情况。我有点让代码正常工作,但在执行错误消息后,它跳过下一个int输入问题,直接进入“输入字符串” 我假设我需要一个while循环,但是我很难弄清楚它到底放在哪里,以及使用什么参数。简单地说,(我想)我需要:w

  • 问题内容: 我相信在AS3中,您应该在循环外初始化所有变量,以提高性能。JavaScript也是如此吗?哪个更好/更快/最佳实践? 要么 问题答案: 有 绝对没有区别 意义还是性能,在JavaScript或ActionScript。 是解析器的指令,而 不是 运行时执行的命令。如果在函数体(*)中的任何位置一次或多次声明了特定的标识符,则该标识符在块中的所有使用将引用局部变量。声明是在循环内部,循

  • 您好,我对jquery没有什么问题。首先,我有: 大众BORA 1.9TDI 1990 1995 奥迪A3 2.0TFSI 2006 2008 但我想实现: VW BORA 1.9TDI 1990 VW BORA 1.9TDI 1991 VW BORA 1.9TDI 1992 VW BORA 1.9TDI 1993 VW BORA 1.9TDI 1994 VW BORA 1.9TDI 1995 A

  • 问题内容: 第二次尝试解决此问题(初始代码不足以突出该问题) 这是无法编译的代码: 我遇到的是试图让AbstractGame中的play方法进行编译。似乎我必须与Game和Player一起在扩展/实现中添加泛型,但我一生都无法理解。 play方法必须在AbstractGame类中是最终方法,并且无法进行强制转换,而且我不想编写另一种方法(如turnTaken)来使它能够正常工作。 编辑:这里要求的