我知道在执行程序时进入 catch block 会产生一些显着的成本,但是,我想知道进入 try{} block 是否也有任何影响,所以我开始在谷歌中寻找答案,有很多意见,但是根本没有基准测试。我找到的一些答案是:
- Java try/catch performance, is it recommended to keep what is inside the try clause to a minimum?
- Try Catch Performance Java
- Java try catch blocks
但是他们没有用事实回答我的问题,所以我决定自己试试。
这就是我所做的。我有一个这种格式的 csv 文件:
host;ip;number;date;status;email;uid;name;lastname;promo_code;
status 之后的所有内容都是可选的,甚至没有对应的 ; ,因此在解析验证时必须进行验证以查看值是否存在,这就是我想到 try/catch 问题的地方。
我在公司继承的当前代码是这样做的:
StringTokenizer st=new StringTokenizer(line,";");
String host = st.nextToken();
String ip = st.nextToken();
String number = st.nextToken();
String date = st.nextToken();
String status = st.nextToken();
String email = "";
try{
email = st.nextToken();
}catch(NoSuchElementException e){
email = "";
}
它重复对带有 uid、name、lastname 和 promo_code 的电子邮件所做的操作。
然后我将所有内容更改为:
if(st.hasMoreTokens()){
email = st.nextToken();
}
事实上它执行得更快。解析没有可选列的文件时。以下是平均时间:
--- Trying:122 milliseconds
--- Checking:33 milliseconds
但是,这就是让我感到困惑的地方以及我要问的原因:当使用 CSV 的所有 8000 行中可选列的值运行示例时,if() 版本的性能仍然优于 try/catch 版本,所以我的问题是
try block 真的不会对我的代码产生任何性能影响吗?
这个例子的平均时间是:
--- Trying:105 milliseconds
--- Checking:43 milliseconds
谁能解释一下这是怎么回事?
非常感谢
最佳答案
是的,try(在 Java 中)没有任何性能影响。编译器不会为 try block 生成 VM 语句。它只是记录 try block 处于 Activity 状态的程序计数器,并将此信息附加到类文件中的方法。然后,当抛出异常时,VM 展开堆栈并在每一帧检查该帧中的程序计数器是否在相关的 try block 中。这(与构建堆栈跟踪一起)成本很高,因此捕获成本很高。但是,尝试是免费的 :)。
不过,对常规控制流使用异常并不是好的做法。
您的代码执行速度更快的原因可能是捕获的成本非常高,以至于它超过了通过简单尝试替换检查所节省的时间。
在不经常触发 catch 的代码中,try catch 可以更快,例如,如果您进入 try 10000 次但只 catch 一次,则 try 方法会比 if-check 更快。不过,这不是一个好的风格,您的显式检查更多标记的方式是首选。
关于java - Java Try/Catch block 的基准测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10978508/