Контрольная точка 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. Тем не менее, это не хороший стиль, и ваш способ явно проверить больше токенов является предпочтительным.