Uma tentativa e captura que não gera uma exceção é mais eficiente que uma condicional?

8

Me deparei com este exemplo recentemente:

Se 999 vezes fora de 1.000, uma exceção não será lançada, a exceção será gerada apenas uma vez. Por outro lado, uma condicional teria sido chamada desnecessariamente 999 vezes, portanto, neste caso, a exceção é superior.

Nesse caso, é C #, mas, de um modo geral, isso é verdade? Eu já havia assumido que as instruções try / catch tinham uma sobrecarga própria que seria igual ao tempo gasto no processamento de uma condição.

É verdade que apenas lançar blocos try / catch em qualquer lugar que normalmente seria condicional seria uma maneira terrível de codificar, mas em termos de recursos essa declaração se mantém?

Jane Panda
fonte
Como o compilador implementa try / catch? Eu suspeito que é um pouco mais complicado do que um simples if ().
Dan Pichelman
8
Experimente. Realmente, experimente. Por que você acreditaria em algo que uma pessoa aleatória na internet disse? Saber como elementos comuns em seu idioma de escolha se comparam ao desempenho vale bem o esforço limitado de realizar um experimento cuidadoso, uma vez.
Kilian Foth
Eu senti que escrever uma comparação de desempenho é uma tarefa muito fácil de estragar, especialmente uma abstrata; Também o exemplo é de um C # livro
Jane Panda
2
Farei o comentário "escrever código legível e não otimizar prematuramente".
djechlin
1
@djechlin Alguém precisava; )
Jane Panda

Respostas:

4

Geralmente é verdade para compiladores de qualidade comercial. No entanto, condicionais podem alcançar eficiências semelhantes usando assume(false)anotações de estilo. A otimização guiada por perfil pode superar os dois.

A razão subjacente é que bons compiladores podem gerar código mais eficiente, fazendo suposições corretas sobre a probabilidade de execução do código. Como a convenção é que as exceções são excepcionais, a maioria dos compiladores (na ausência de dados de criação de perfil) gera código ideal quando as exceções são realmente raras.

Por exemplo, o código de tratamento de exceções pode ser colocado em seu próprio segmento e somente ser paginado quando a primeira exceção ocorrer. Isso significa que o cache da CPU pode ser usado com mais eficiência, armazenando apenas código não excepcional.

MSalters
fonte
E compiladores dinâmicos, como, por exemplo, encontrados em quase todos os mecanismos JavaScript, JVMs e implementações de Smalltalk, nem precisam fazer suposições sobre a probabilidade de ramificações, eles podem apenas contá-las. É como o PGO em esteróides: re-criação de perfil e otimização repetidas vezes, usando a carga de trabalho real que está sendo executada agora para orientar a otimização do código que está sendo executado no momento .
Jörg W Mittag
4

Existem cenários para usar try / catch e outros para usar condicionais.

Usar uma tentativa / captura não prejudica o desempenho, conforme descrito extensivamente aqui

O custo geral de um bloco try ... catch que nunca lida com uma exceção é de alguns bytes de memória

Além do desempenho, o tratamento adequado de exceções é importante. A última coisa que você deseja é que erros não detectados sejam mostrados a um usuário, desempenho de buggy ou aplicativo travado após a ocorrência de um problema.

Erich
fonte
3
+1 desempenho não é a única coisa importante para se preocupar ou nós vala interfaces gráficas de usuário amigável em uma instância
RhysW
2
Essa é uma ótima leitura sobre exceções.
Jane Panda
-1

Um exemplo de um melhor desempenho usando try / catch em vez de condicional é quando se lida com Dicionários, quando se pergunta se a chave contém O (n), em vez de apenas tentar acessar / adicionar a chave e capturar a exceção em potencial.

try
{
    dict.Add(key, val);
}
catch (Exception)
{

    dict[key] = val;
}
Enrique Medina
fonte
Uau, se isso for verdade, estou realmente surpreso! Você tem uma referência?
5
-1. Não faça isso. Se você estiver preocupado com a sobrecarga de desempenho ao verificar se a chave existe, use TryGetValue (). msdn.microsoft.com/en-us/library/bb347013.aspx
riwalk
obrigado por apontar isso, o mínimo que eu quero é aconselhar uma prática ruim. Eu uso isso há muito tempo, porém, um bom hábito que se tornou obsoleto, eu acho. De qualquer forma, meu objetivo era mostrar que existem cenários em que capturar uma exceção pode ser uma opção melhor do que perguntar se é válido fazer alguma coisa.
Enrique Medina