8

我知道在执行程序时进入 catch 块有一些显着的成本,但是,我想知道进入 try{} 块是否也有任何影响,所以我开始在谷歌中寻找答案,有很多意见,但没有基准测试全部。我找到的一些答案是:

  1. Java try/catch 性能,是否建议将 try 子句中的内容保持在最低限度?
  2. 尝试 Catch 性能 Java
  3. Java try catch 块

但是他们没有用事实回答我的问题,所以我决定自己尝试一下。

这就是我所做的。我有一个这种格式的 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 块真的对我的代码没有任何性能影响吗?

此示例的平均时间为:

--- Trying:105 milliseconds
--- Checking:43 milliseconds

有人可以解释这里发生了什么吗?

非常感谢

4

1 回答 1

12

是的,try(在 Java 中)对性能没有任何影响。编译器不会为 try 块生成 VM 语句。它只是记录 try 块处于活动状态的程序计数器,并将此信息附加到类文件中的方法。然后,当抛出异常时,VM 展开堆栈并在每一帧检查该帧中的程序计数器是否在相关的 try 块中。这(连同构建堆栈跟踪)非常昂贵,因此捕获成本很高。但是,尝试是免费的:)。

尽管如此,对常规控制流使用异常并不是一个好习惯。

您的代码执行得更快的原因可能是捕获的成本非常高,以至于它超过了通过简单的尝试替换检查所节省的时间。

Try catch can be faster in code where the catch is triggered not very often, e.g., if you go into the try 10000 times but only catch once, the try method would be faster than the if-check. Still, this is no good style and your way of explicitly checking for more tokens is to be preferred.

于 2012-06-11T10:40:04.520 回答