Контрольная точка Java Try/Catch Block

Я знаю, что переход в блокирующий блок имеет некоторую значительную стоимость при выполнении программы, однако мне было интересно, было ли вхождение в блок try {}, и я начал искать ответ в google со многими мнениями, но нет бенчмаркинга вообще. Некоторые ответы, которые я нашел, были:

Однако они не ответили на мой вопрос фактами, поэтому я решил попробовать это для себя.

Вот что я сделал. У меня есть файл 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

однако вот что меня смутило и почему я спрашиваю: при запуске примера со значениями для дополнительных столбцов во всех 8000 строках CSV версия if() все же работает лучше, чем версия try/catch, поэтому мой вопрос

Действительно ли блок try не влияет на мой код на производительность?

Среднее время для этого примера:

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

Может кто-нибудь объяснить, что здесь происходит?

Спасибо большое

Ответ 1

Да, попытка (на Java) не влияет на производительность. Компилятор не генерирует никаких операторов VM для блока try. Он просто записывает счетчики программ, между которыми активен блок try, и прикрепляет эту информацию к методу в файле класса. Затем, когда генерируется исключение, VM разматывает стек и проверяет в каждом кадре, находится ли счетчик программы в этом кадре в соответствующем блоке try. Это (вместе со строительством трассировки стека) довольно дорогостоящее, поэтому ловить дорого. Тем не менее, попытка бесплатна:).

Тем не менее, не рекомендуется использовать исключения для регулярного потока управления.

Причина, по которой ваш код работает быстрее, вероятно, заключается в том, что улавливание является настолько дорогостоящим, что оно перевешивает время, сэкономленное путем замены проверки простой попыткой.

Попробуйте поймать быстрее в коде, где улов запускается не очень часто, например, если вы входите в попытку 10000 раз, но только поймаете один раз, метод try будет быстрее, чем if-check. Тем не менее, это не хороший стиль, и ваш способ явно проверить больше токенов является предпочтительным.