抛出并捕获异常,或使用instanceof?

Rus*_*lan 21 java performance exception instanceof throws

我在变量中有一个异常(没有抛出).

什么是最好的选择?

Exception exception = someObj.getExcp();
try {
    throw exception;
} catch (ExceptionExample1 e) {
    e.getSomeCustomViolations();
} catch (ExceptionExample2 e) {
    e.getSomeOtherCustomViolations(); 
}
Run Code Online (Sandbox Code Playgroud)

要么

Exception exception = someObj.getExcp();
if (exception instanceof ExceptionExample1) {
    exception.getSomeCustomViolations();
} else if (exception instanceof ExceptionExample2) {
    exception.getSomeOtherCustomViolations();
}
Run Code Online (Sandbox Code Playgroud)

Boa*_*ann 9

我建议使用,instanceof因为它可能会更快.抛出异常是一项复杂而昂贵的操作.在没有发生异常的情况下,JVM被优化为快速.例外应该是例外.

请注意,该throw技术可能无法编译,如果您的异常类型是一个经过检查的异常,编译器会抱怨您必须捕获该类型或将其声明为抛出(else { ... }如果您使用该instanceof技术,则对应于一个子句),这可能或者可能没有帮助,具体取决于您希望如何处理不属于某个特定子类型的异常.

  • `instanceof` 应该更快,但异常并不慢,可以通过 JIT 进行优化:http://stackoverflow.com/a/299214/1851024。 (2认同)

dis*_*tor 8

讨厌爆所有人的泡沫,但使用try/catch.这并不是说它是"正确"的方式,但如果表现是关键那么那就是赢家.以下是来自以下计划的结果:

运行1

  • 子运行1:实例:130毫秒
  • 子运行1:尝试/捕获:118毫秒
  • 子运行2:实例:96毫秒
  • 子运行2:尝试/捕获:93毫秒
  • 子运行3:实例:100毫秒
  • 子运行3:尝试/捕获:99毫秒

跑2

  • 子运行1:实例:140毫秒
  • 子运行1:尝试/捕获:111毫秒
  • 子运行2:实例:92毫秒
  • 子运行2:尝试/捕获:92毫秒
  • 子运行3:实例:105毫秒
  • 子运行3:尝试/捕获:95毫秒

跑3

  • 子运行1:实例:140毫秒
  • 子运行1:尝试/捕获:135毫秒
  • 子运行2:实例:107毫秒
  • 子运行2:尝试/捕获:88毫秒
  • 子运行3:实例:96毫秒
  • 子运行3:尝试/捕获:90毫秒

测试环境

  • Java:1.7.0_45
  • Mac OSX Mavericks

折扣每次运行的热身子运行instanceof方法只能达到最佳性能try/catch.该方法的平均值(折扣热身)instanceof为98毫秒,平均值try/catch为92毫秒.

请注意,我没有改变每种方法的测试顺序.我总是测试一块instanceof然后块try/catch.我希望看到其他结果与这些发现相矛盾或得到证实.

public class test {

    public static void main (String [] args) throws Exception {
        long start = 0L;
        int who_cares = 0; // Used to prevent compiler optimization
        int tests = 100000;

        for ( int i = 0; i < 3; ++i ) {
            System.out.println("Testing instanceof");
            start = System.currentTimeMillis();
            testInstanceOf(who_cares, tests);
            System.out.println("instanceof completed in "+(System.currentTimeMillis()-start)+" ms "+who_cares);

            System.out.println("Testing try/catch");
            start = System.currentTimeMillis();
            testTryCatch(who_cares, tests);
            System.out.println("try/catch completed in "+(System.currentTimeMillis()-start)+" ms"+who_cares);
        }
    }

    private static int testInstanceOf(int who_cares, int tests) {
        for ( int i = 0; i < tests; ++i ) {
            Exception ex = (new Tester()).getException();
            if ( ex instanceof Ex1 ) {
                who_cares = 1;
            } else if ( ex instanceof Ex2 ) {
                who_cares = 2;
            }
        }
        return who_cares;
    }

    private static int testTryCatch(int who_cares, int tests) {
        for ( int i = 0; i < tests; ++i ) {
            Exception ex = (new Tester()).getException();
            try {
                throw ex;
            } catch ( Ex1 ex1 ) {
                who_cares = 1;
            } catch ( Ex2 ex2 ) {
                who_cares = 2;
            } catch ( Exception e ) {}
        }
        return who_cares;
    }

    private static class Ex1 extends Exception {}

    private static class Ex2 extends Exception {}

    private static java.util.Random rand = new java.util.Random();

    private static class Tester {
        private Exception ex;
        public Tester() {
            if ( rand.nextBoolean() ) {
                ex = new Ex1();
            } else {
                ex = new Ex2();
            }
        }
        public Exception getException() {
            return ex;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我得到的结果不一致。有时一个比另一个快,但并非总是如此。如果你看一下实际时间,你会发现 `instanceof` 一开始比较慢,但经过大约 3 次迭代后,`instanceof` 的性能比 `try/catch` 更好。这可能是由于 JIT 优化造成的,可能不代表实际应用程序。当运行时针对高度重复的操作不断优化时,即使不是不可能,也很难在测试平台中获得准确的数字。 (2认同)