java - Java Try/Catch block 的基准测试

标签 java try-catch

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

  1. Java try/catch performance, is it recommended to keep what is inside the try clause to a minimum?
  2. Try Catch Performance Java
  3. 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/

相关文章:

java - 异常情况下的返回语句

r - 如何在 R 中使用 tryCatch

java - 以编程方式禁用在 Intranet 中运行并呈现 .xhtml 页面的站点的 IE-8 兼容模式

java - Intellij 相当于 Eclipse syso

java - 重写 AbstractTableModel 中的 "getValueAt"将 Map 绑定(bind)到 JTable

java - finally block 的意义

c++ - std::bad_alloc 未陷入任何调用堆栈帧

c++ - 无法在 `catch(const std::exception &ex)` 中捕获 std::invalid_argument

java - Tomcat 添加 context-path 到 urls

java - 如何检查Java泛型类型是否是Comparator的子类?