依稀还记得,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 ms
no_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 ms
no_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 ms
no_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 ms
new 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 ms
catch 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位