try-catch怎么能放在循环内部呢?这样多影响性能啊?你会不会写代码?
去nmd吧,下面就让你看看try-catch对性能的影响,把你狗头锤烂!!!
耗时测试
先说结论,当无异常发生时,循环内外加try-catch效率相差无几;如果循环内部异常抛出过多,则会显著降低执行效率。
代码
循环体外try-catch
public static Long outLoop(){
int n = 0;
Long startTime = System.currentTimeMillis();
try{
for (int i = 0; i < loopTime; i++) {
++n;
}
}catch (Exception e){
}
Long endTime = System.currentTimeMillis();
return endTime-startTime;
}
循环体内try-catch
抛异常
public static Long innerThrowLoop(){
int n = 0;
Long startTime = System.currentTimeMillis();
for (int i = 0; i < loopTime; i++) {
try {
++n;
if(n == 1){
throw new Exception("");
}
}catch (Exception e){
}
}
Long endTime = System.currentTimeMillis();
return endTime-startTime;
}
无异常
public static Long innerLoop(){
int n = 0;
Long startTime = System.currentTimeMillis();
for (int i = 0; i < loopTime; i++) {
try {
++n;
}catch (Exception e){
}
}
Long endTime = System.currentTimeMillis();
return endTime-startTime;
}
耗时
采用循环1亿次进行耗时测试:
底层原理
从字节码角度分析为什么循环内外try-catch在不发生异常时效率一样。
代码
package exception;
public class TryCatchSimpleDemo {
public static void main(String[] args) {
try{
System.out.println("hello world");
}catch (Exception e){
}
}
}
命令
javac TryCatchSimpleDemo.java
javap -c TryCatchSimpleDemo.class > code.txt
字节码分析
Compiled from "TryCatchSimpleDemo.java"
public class exception.TryCatchSimpleDemo {
public exception.TryCatchSimpleDemo();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String hello world
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: goto 12
11: astore_1
12: return
Exception table:
from to target type
0 8 11 Class java/lang/Exception
}
异常表
在字节码尾部可以看到如下异常表,记录try-catch起止的行数和异常类型。
- from:起始行数
- to:终止行数
- target:异常处理开始位置
- type:异常类型
Exception table:
from to target type
0 8 11 Class java/lang/Exception
从字节码指令可以看出,当代码运行时出错时,会先判断出错数据是否在 from 到 to 的范围内,如果是则从 target 标志位往下执行,如果没有出错,直接 goto 到 return。也就是说,如果代码不出错的话,性能几乎是不受影响的,和正常的代码的执行逻辑是一样的
总结
try-catch无论放在循环内外,在不发生异常时对效率的影响微乎其微,由于try-catch内部的指令不能进行重排序,因此会造成一些影响但是不大。
在业务开发中主要还是考虑业务场景在决定是否要在循环内部使用try-catch。下次leader说不行,直接怼回去!