Java Try / Catch Block的基准测试

时间:2012-06-11 10:36:11

标签: java try-catch

我知道在执行程序时进入catch块有一些显着的成本,但是,我想知道是否进入try {}块也有任何影响因此我开始在google中寻找答案,但有很多意见,但是根本没有基准。我发现的一些答案是:

  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
  4. 然而他们没有用事实来回答我的问题,所以我决定亲自尝试。

    这就是我的所作所为。我有一个这种格式的csv文件:

    host;ip;number;date;status;email;uid;name;lastname;promo_code;

    其中所有状态都是可选的,甚至没有相应的; ,所以在解析验证时必须要查看值是否存在,这就是我想到的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
    

    有人能解释一下这里发生了什么吗?

    非常感谢

1 个答案:

答案 0 :(得分:11)

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

但是,对常规控制流使用异常仍然不是好习惯。

您的代码执行速度更快的原因可能是捕获成本非常高,以至于通过简单的尝试替换支票可以节省时间。

尝试catch在代码中可以更快地触发catch,例如,如果你进入try 10000次但只捕获一次,try方法将比if-check更快。尽管如此,这并不是一种好的风格,而且明确检查更多代币的方式也是首选。