Data de postagem: Oct 01, 2010 7:39:44 PM
Normalmente as linguagens de programação com suporte a exceções partem do pressuposto que exceções são ... "exceções". Devem ser raras e indicam uma quebra abrupta do fluxo normal de um processamento.
Com base neste pressuposto, os compiladores e interpretadores buscam eliminar os custos das estruturas de captura de exceções para o cenário mais frequente, quando não ocorrem exceções. Esta otimização normalmente implica na geração um custo elevado no momento da captura de uma exceção.
As implicações práticas deste comportamento é que devemos evitar a criação de códigos onde a geração de exceções seja frequente, principalmente em laços. Nestes casos, o try...catch deve ser substituído por uma código que teste um comportamento sem o uso da tentativa e erro.
Exemplo com exceções:
function test(n) {
if (n % 2) {
throw new Error("Fail!");
}
}
var failCount = 0;
for (var i = 0; i < 10000; ++i) {
try {
test(i);
} catch (e) {
failCount++;
}
}
RunTime: 62 milisegundos
Exemplo sem exceções:
function test(n) {
return !(n % 2);
}
var failCount = 0;
for (var i = 0; i < 10000; ++i) {
if (!test(i)) {
failCount++;
}
}
RunTime: 15 milisegundos
Os exemplos acima são extremos e tem o objetivo de demonstrar o custo de uma exceção. No dia-a-dia, observamos casos aparentemente inocentes, mas igualmente danosos. Exemplos:
Testar se um campo existe em um DataSet, acessando-o como uma propriedade e ignorando o erro caso não exista. Nestes casos, o try/catch pode ser substituído por um findField.
Tentar identificar a tabela de uma chave tentando acessar um campo que somente existe em uma tabela. É mais elegante e otimizado utilizar o método dbCache.findKey(), que retorna um objeto onde uma das propriedades é o tableName.