Na seção Quando usar exceção no programador pragmático , o livro escreve que, em vez de:
retcode = OK;
if (socket.read(name) != OK) {
retcode = BAD_READ;
}
else {
processName(name);
if (socket.read(address) != OK) {
retcode = BAD_READ;
}
else {
processAddress(address);
if (socket.read(telNo) != OK) {
retcode = BAD_READ;
}
else {
// etc, etc...
}
}
}
return retcode;
, Eles preferem:
retcode = OK;
try {
socket.read(name);
process(name);
socket.read(address);
processAddress(address);
socket.read(telNo);
// etc, etc...
}
catch (IOException e) {
retcode = BAD_READ;
Logger.log( "Error reading individual: " + e.getMessage());
}
return retcode;
simplesmente porque parece mais limpo. Eu sou tudo para o código mais limpo, no entanto, não é desnecessário captura de exceções um gargalo de desempenho?
Eu posso entender que devemos desistir de otimização minúscula para código mais limpo (pelo menos 99% das vezes), no entanto, pelo que sei, capturar exceções pertence à classe de código que possui um atraso notável no tempo de execução. Por isso, eu queria saber qual é a justificativa de que o segundo trecho de código é preferido sobre o primeiro código?
Ou melhor, qual código você prefere?
java
exception-handling
language-agnostic
Pacerier
fonte
fonte
Respostas:
As exceções geralmente são mais lentas se forem lançadas. Geralmente, as exceções em situações como essa são raras, portanto não é algo com que você deva se preocupar. Você realmente só deve se preocupar com o desempenho das exceções, se elas estiverem acontecendo o tempo todo e, portanto, são um fator significativo.
O segundo código é melhor porque é muito mais fácil seguir a lógica. A manipulação de erros está bem localizada. A única objeção é que, se você estiver usando exceções, use exceções. Não pegue as exceções e, em seguida, retorne um código de erro.
fonte
Bem, como também dizem, as exceções devem lidar com casos excepcionais , e como esse é um caso excepcional (isto é, algo que acontece muito pouco), eu diria que isso também se aplica aqui.
Além disso, eu aconselho a não otimizar micro coisas como essa. Concentre-se mais na legibilidade do código , pois você estará gastando muito mais tempo lendo o código do que escrevendo um novo código.
Para realmente garantir que esse seja um gargalo de desempenho, faça alguns perfis, analise e concentre-se nas tarefas mais críticas baseadas nessa análise.
fonte
De onde você sabe disso? Como você define "atraso perceptível"?
Esse é exatamente o tipo de mito de desempenho vago (e completamente errado) que leva a otimizações prematuras inúteis.
Lançar e capturar uma exceção pode ser lento em comparação à adição de dois números, mas é completamente insignificante comparado à leitura de dados de um soquete. Você provavelmente poderia lançar e capturar mil exceções ao mesmo tempo em que leu um único pacote de rede. E não estamos falando de milhares de exceções aqui, apenas uma única.
fonte
Eu concordo com as respostas que você já recebeu dizendo que esse é um caso excepcional, portanto, é razoável usar o tratamento de exceções.
Abordando suas preocupações de desempenho mais diretamente, acho que você precisa manter um senso de escala sobre as coisas. Lançar / capturar uma exceção nessas circunstâncias provavelmente levará uma da ordem de um microssegundo. Conforme o controle de fluxo é lento, muitas vezes mais lento que o normal
if
, não há dúvida sobre isso.Ao mesmo tempo, lembre-se de que o que você está fazendo aqui é ler dados de uma rede. A 10 megabits por segundo (lento para uma rede local, mas bastante rápida conforme as conexões com a Internet), está na mesma ordem que o tempo para ler um byte de informação.
Obviamente, essa sobrecarga só ocorre quando você realmente lança a exceção - quando não é lançada, geralmente há pouca ou nenhuma sobrecarga (pelo menos pelo que vi, a sobrecarga mais significativa não é do manipulação de exceção em si, a partir da adição de mais fluxos de controle em potencial, dificultando a otimização do código para o compilador).
Nesse caso, quando uma exceção é lançada, seus dados de gravação no log. Dada a natureza do registro, é muito provável que você libere essa saída assim que você a escreve (para garantir que ela não seja perdida). Gravar em disco é (novamente) uma operação bastante lenta - você precisa de um SSD de classe empresarial razoavelmente rápido para chegar a dezenas de milhares de IOPs / segundo. Um disco usado para o log pode ser facilmente limitado a centenas de IOPs / segundo.
Conclusão: há casos em que a sobrecarga de manipulação de exceção pode ser significativa, mas esse quase certamente não é um deles.
fonte