Sabemos que é caro capturar exceções. Mas, também é caro usar um bloco try-catch em Java, mesmo que uma exceção nunca seja lançada?
Encontrei a pergunta / resposta do estouro de pilha Por que os blocos de tentativa são caros? , mas é para .NET .
java
performance
try-catch
jsedano
fonte
fonte
try { /* do stuff */ } finally { /* make sure to release resources */ }
é legal e útilfinally
bloco usando atry-with-resources
Respostas:
try
quase não tem nenhuma despesa. Em vez de fazer o trabalho de configurar otry
tempo de execução, os metadados do código são estruturados no tempo de compilação, de modo que, quando uma exceção é lançada, ele agora faz uma operação relativamente cara, subindo a pilha e ver setry
existem blocos que capturariam isso. exceção. Do ponto de vista de um leigo, tambémtry
pode ser livre. Na verdade, está lançando a exceção que lhe custa - mas, a menos que você esteja lançando centenas ou milhares de exceções, você ainda não perceberá o custo.try
tem alguns custos menores associados a ele. Java não pode fazer algumas otimizações no código em umtry
bloco que faria de outra forma. Por exemplo, o Java geralmente reorganiza as instruções em um método para torná-lo mais rápido - mas o Java também precisa garantir que, se uma exceção for lançada, a execução do método seja observada como se suas instruções, como escritas no código-fonte, fossem executadas em ordem até alguma linha.Como em um
try
bloco, uma exceção pode ser lançada (em qualquer linha do bloco try! Algumas exceções são lançadas de forma assíncrona, como chamarstop
um Thread (que foi descontinuado) e, além disso, o OutOfMemoryError pode acontecer em quase qualquer lugar), e ainda assim pode ser capturado e o código continua sendo executado posteriormente no mesmo método, é mais difícil pensar em otimizações que podem ser feitas, portanto, é menos provável que isso aconteça. (Alguém precisaria programar o compilador para executá-los, argumentar e garantir a correção, etc. Seria uma grande dor para algo que deveria ser 'excepcional'). Mas, novamente, na prática, você não notará coisas assim.fonte
try...finally
bloco semcatch
também impede algumas otimizações?Exception
objeto é o que leva a maior parte do tempo.Vamos medir, sim?
No meu computador, isso imprime algo como:
Pelo menos neste exemplo trivial, a instrução try não teve impacto mensurável no desempenho. Sinta-se livre para medir os mais complexos.
De um modo geral, recomendo não se preocupar com o custo de desempenho das construções de linguagem até que você tenha evidências de um problema real de desempenho em seu código. Ou, como Donald Knuth colocou : "a otimização prematura é a raiz de todo mal".
fonte
-XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly
, o loop e a adição estão presentes no código nativo gerado. E não, os métodos abstratos não são incorporados, porque o chamador não é apenas compilado no tempo (presumivelmente, porque não é chamado o suficiente).try
/catch
pode ter algum impacto no desempenho. Isso ocorre porque impede que a JVM faça algumas otimizações. Joshua Bloch, em "Java Efetivo", disse o seguinte:fonte
Sim, como os outros disseram, um
try
bloco inibe algumas otimizações entre os{}
personagens que o cercam. Em particular, o otimizador deve assumir que uma exceção pode ocorrer em qualquer ponto do bloco, portanto, não há garantia de que as instruções sejam executadas.Por exemplo:
Sem o
try
, o valor calculado para atribuir ax
pode ser salvo como uma "subexpressão comum" e reutilizado para atribuir ay
. Mas por causa dotry
não há garantia de que a primeira expressão tenha sido avaliada, a expressão deve ser recalculada. Normalmente, isso não é um grande problema no código "linear", mas pode ser significativo em um loop.Note-se, no entanto, que isso se aplica SOMENTE ao código JITCed. O javac faz apenas uma pequena quantidade de otimização e o custo do interpretador de bytecodes é zero para entrar / sair de um
try
bloco. (Não há bytecodes gerados para marcar os limites do bloco.)E para bestsss:
Resultado:
saída javap:
Não "GOTO".
fonte
catch/finally
quadro.finally
no bytecode, étry/catch(Throwable any){...; throw any;}
E tem uma instrução catch w / a frame e Throwable que DEVE SER definida (não nula) e assim por diante. Por que você tenta discutir sobre o tópico, pode verificar pelo menos alguns códigos de bytes? A diretriz atual para impl. Finalmente, copie os blocos e evite a seção goto (impl anterior), mas os bytecodes precisam ser copiados dependendo de quantos pontos de saída existem.Para entender por que as otimizações não podem ser executadas, é útil entender os mecanismos subjacentes. O exemplo mais sucinto que pude encontrar foi implementado nas macros C em: http://www.di.unipi.it/~nids/docs/longjump_try_trow_catch.html
Os compiladores geralmente têm dificuldade em determinar se um salto pode ser localizado em X, Y e Z, para ignorar otimizações que não podem garantir a segurança, mas a implementação em si é bastante leve.
fonte
Mais uma marca de microbench ( fonte ).
Criei um teste no qual medi a versão do código try-catch e no-try-catch com base em uma porcentagem de exceção. A porcentagem de 10% significa que 10% dos casos de teste tiveram divisão por zero casos. Em uma situação, ele é tratado por um bloco try-catch, na outra por um operador condicional. Aqui está a minha tabela de resultados:
O que diz que não há diferença significativa entre nenhum desses casos.
fonte
Eu achei a captura do NullPointException bastante cara. Para operações de 1.2k, o tempo era de 200ms e 12ms quando eu o manipulava da mesma maneira com a
if(object==null)
qual foi bastante aprimorado para mim.fonte