读书人

java Exception 性能有关问题

发布时间: 2013-04-05 10:24:33 作者: rapoo

java Exception 性能问题

依稀还记得,try{}之后的代码块应尽量越少越好,难道代码被try{}catch(){}包围之后会降低运行效率吗?

测试一下:

package exception;public class TestTry_Catch{public static boolean try_catch(){try{return true;} catch (Exception e){return false;}}public static boolean no_try_catch(){return true;}public static void main(String[] args){long current1 = System.currentTimeMillis();long time = 10000000000l;for (long i = 0l; i < time; i++)try_catch();long current2 = System.currentTimeMillis();for (long j = 0l; j < time; j++)no_try_catch();long current3 = System.currentTimeMillis();System.out.println("try_catch time : " + (current2 - current1) + " ms");System.out.println("no_try_catch time : " + (current3 - current2) + " ms");}}

?下面是console输出:

try_catch time : 4843 msno_try_catch time : 4683 ms

?这么多次,相差依然很小,在不会发生异常的情况下try_catch方法和no_try_catch方法运行的时间基本相差无几,在即时编译时try_catch方法比no_try_catch方法应花费稍多时间

?

下面再看一个更有趣的,当把return type改为void 时,代码:

package exception;public class TestTry_Catch{public static void try_catch(){try{// return true;} catch (Exception e){// return false;}}public static void no_try_catch(){// return true;}public static void main(String[] args){long current1 = System.currentTimeMillis();long time = 10000000000l;for (long i = 0l; i < time; i++)try_catch();long current2 = System.currentTimeMillis();for (long j = 0l; j < time; j++)no_try_catch();long current3 = System.currentTimeMillis();System.out.println("try_catch time : " + (current2 - current1) + " ms");System.out.println("no_try_catch time : " + (current3 - current2) + " ms");}}

?console 输出:

try_catch time : 4772 msno_try_catch time : 4918 ms

?try_catch 比no_try_catch花费的时间更少了,这该怎样解释呢?

?

让方法进行一些计算吧,不去创建对象,因为可能会触发GC,只是去计算一下1+1

package exception;public class TestTry_Catch{public static void try_catch(){try{int a = 1 + 1;int b = a + 3;} catch (Exception e){// return false;}}public static void no_try_catch(){int a = 1 + 1;int b = a + 3;}public static void main(String[] args){long current1 = System.currentTimeMillis();long time = 10000000000l;for (long i = 0l; i < time; i++)try_catch();long current2 = System.currentTimeMillis();for (long j = 0l; j < time; j++)no_try_catch();long current3 = System.currentTimeMillis();System.out.println("try_catch time : " + (current2 - current1) + " ms");System.out.println("no_try_catch time : " + (current3 - current2) + " ms");}}

?console输出:

try_catch time : 4957 msno_try_catch time : 4934 ms

?

我开始怀疑 try{}catch(){}代码块越短越好 这句话的正确性了

?

下面测一下异常对象产的的耗时和普通对象产生的耗时比较:

?

package exception;import exception.entity.My_Exception;public class New_Object_Exception{public static void main(String[] args){for (int i = 0; i < 10000; i++)new Throwable();long number = 100000l;long current1 = System.currentTimeMillis();for (long j = 0l; j < number; j++)new My_Exception();long current2 = System.currentTimeMillis();for (long i = 0l; i < number; i++)new Exception();long current3 = System.currentTimeMillis();System.out.println("new My_Exception time : " + (current2 - current1) + " ms");System.out.println("new Exception time : " + (current3 - current2) + " ms");}}

?console输出:

new My_Exception time : 113 msnew Exception time : 144 ms

?相差很小,一个数量级,无视GC了

?

下面测一下抛出异常到接收到异常的时间,代码如下:

?

package exception;import exception.entity.My_Exception;public class Catch_Exception{public static void main(String[] args){long time = 100000l;for (int i = 0; i < 10000; i++){new Throwable();}long current1 = System.currentTimeMillis();for (long i = 0l; i < time; i++){try{throw new Exception();} catch (Exception e){}}long current2 = System.currentTimeMillis();for (long i = 0l; i < time; i++){try{throw new My_Exception();} catch (My_Exception e){}}long current3 = System.currentTimeMillis();System.out.println("catch Exception : " + (current2 - current1) + " ms");System.out.println("catch My_Exception : " + (current3 - current2) + " ms");}}

?console输出:

?

catch Exception : 77 mscatch My_Exception : 64 ms

?

?

贴一下jdk中Throwable 类的getMessage(), getStackTrace()源码

?

getMessage():

    public String getMessage() {        return detailMessage;    }

?detailMessage只是Throwable类的一个私有变量

 private String detailMessage;

?

getStackTrace():

    public StackTraceElement[] getStackTrace() {        return getOurStackTrace().clone();    }

?getOurStackTrace():

    private synchronized StackTraceElement[] getOurStackTrace() {        // Initialize stack trace field with information from        // backtrace if this is the first call to this method        if (stackTrace == UNASSIGNED_STACK ||            (stackTrace == null && backtrace != null) /* Out of protocol state */) {            int depth = getStackTraceDepth();            stackTrace = new StackTraceElement[depth];            for (int i=0; i < depth; i++)                stackTrace[i] = getStackTraceElement(i);        } else if (stackTrace == null) {            return UNASSIGNED_STACK;        }        return stackTrace;    }

?如果不是自定义的异常对象,大概没必要去调这个方法,如果不调这个方法抛出异常,捕获异常,貌似对性能也没什么影响

?

关于异常,各有各的想法吧

?

另外我的电脑配置:i5 win7 64位 4G内存, jdk : jdk1.7.0_10 b18 64位

读书人网 >编程

热点推荐