What are the effects of exceptions on performance in Java?

前端 未结 17 2678
情深已故
情深已故 2020-11-22 01:21

Question: Is exception handling in Java actually slow?

Conventional wisdom, as well as a lot of Google results, says that exceptional logic shouldn\'t be used for n

17条回答
  •  半阙折子戏
    2020-11-22 01:45

    I've extends the answers given by @Mecki and @incarnate, without stacktrace filling for Java.

    With Java 7+, we can use Throwable(String message, Throwable cause, boolean enableSuppression,boolean writableStackTrace). But for Java6, see my answer for this question

    // This one will regularly throw one
    public void method4(int i) throws NoStackTraceThrowable {
        value = ((value + i) / i) << 1;
        // i & 1 is equally fast to calculate as i & 0xFFFFFFF; it is both
        // an AND operation between two integers. The size of the number plays
        // no role. AND on 32 BIT always ANDs all 32 bits
        if ((i & 0x1) == 1) {
            throw new NoStackTraceThrowable();
        }
    }
    
    // This one will regularly throw one
    public void method5(int i) throws NoStackTraceRuntimeException {
        value = ((value + i) / i) << 1;
        // i & 1 is equally fast to calculate as i & 0xFFFFFFF; it is both
        // an AND operation between two integers. The size of the number plays
        // no role. AND on 32 BIT always ANDs all 32 bits
        if ((i & 0x1) == 1) {
            throw new NoStackTraceRuntimeException();
        }
    }
    
    public static void main(String[] args) {
        int i;
        long l;
        Test t = new Test();
    
        l = System.currentTimeMillis();
        t.reset();
        for (i = 1; i < 100000000; i++) {
            try {
                t.method4(i);
            } catch (NoStackTraceThrowable e) {
                // Do nothing here, as we will get here
            }
        }
        l = System.currentTimeMillis() - l;
        System.out.println( "method4 took " + l + " ms, result was " + t.getValue() );
    
    
        l = System.currentTimeMillis();
        t.reset();
        for (i = 1; i < 100000000; i++) {
            try {
                t.method5(i);
            } catch (RuntimeException e) {
                // Do nothing here, as we will get here
            }
        }
        l = System.currentTimeMillis() - l;
        System.out.println( "method5 took " + l + " ms, result was " + t.getValue() );
    }
    

    Output with Java 1.6.0_45, on Core i7, 8GB RAM:

    method1 took 883 ms, result was 2
    method2 took 882 ms, result was 2
    method3 took 32270 ms, result was 2 // throws Exception
    method4 took 8114 ms, result was 2 // throws NoStackTraceThrowable
    method5 took 8086 ms, result was 2 // throws NoStackTraceRuntimeException
    

    So, still methods which returns values are faster, compared to methods throwing exceptions. IMHO, we can't design a clear API just using return types for both success & error flows. Methods which throws exceptions without stacktrace are 4-5 times faster than normal Exceptions.

    Edit: NoStackTraceThrowable.java Thanks @Greg

    public class NoStackTraceThrowable extends Throwable { 
        public NoStackTraceThrowable() { 
            super("my special throwable", null, false, false);
        }
    }
    

提交回复
热议问题