En la sección Cuándo usar la excepción en El programador pragmático , el libro escribe que en lugar 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;
, ellos prefieren:
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;
simplemente porque se ve más ordenado. Estoy todo para el código más limpio, sin embargo, no es necesaria la captura de excepciones de un cuello de botella?
Puedo entender que deberíamos renunciar a la optimización minúscula para un código más ordenado (al menos el 99% de las veces), sin embargo, por lo que sé, las excepciones de captura pertenecen a la clase de código que tiene un retraso notable en el tiempo de ejecución. Por lo tanto, me preguntaba cuál es la justificación de que se prefiere la segunda parte del código sobre el primer código.
O más bien, ¿qué código preferirías?
java
exception-handling
language-agnostic
Pacerier
fuente
fuente
Respuestas:
Las excepciones suelen ser más lentas si realmente se lanzan. Por lo general, las excepciones en situaciones como esta son raras, por lo que no es algo de lo que deba preocuparse. Realmente solo debe preocuparse por el desempeño de las excepciones si están sucediendo todo el tiempo y, por lo tanto, son un factor significativo.
El segundo código es mejor porque es mucho más fácil seguir la lógica. El manejo de errores está bien localizado. La única objeción es que si está usando excepciones, entonces use excepciones. No atrape las excepciones y luego devuelva un código de error.
fuente
Bueno, como también dicen, las excepciones deberían manejar los casos excepcionales , y dado que este es un caso excepcional (es decir, algo que ocurre muy poco y en el medio), diría que esto también se aplica aquí.
Además, aconsejaría que no se optimicen las cosas como esta. Céntrese más en la legibilidad del código , ya que pasará mucho más tiempo leyendo código que escribiendo código nuevo.
Para asegurarse realmente de que este es un cuello de botella en el rendimiento, haga algunos perfiles y analice y concéntrese en las tareas más críticas basadas en ese análisis.
fuente
¿De dónde sabes eso? ¿Cómo define "retraso notable"?
Este es exactamente el tipo de mito de rendimiento vago (y completamente incorrecto) que conduce a optimizaciones prematuras inútiles.
Lanzar y atrapar una excepción puede ser lento en comparación con sumar dos números, pero es completamente insignificante en comparación con la lectura de datos de un socket. Probablemente podría lanzar y atrapar mil excepciones al mismo tiempo que ha leído un solo paquete de red. Y no estamos hablando de miles de excepciones aquí, solo una.
fuente
Estoy de acuerdo con las respuestas que ya ha recibido diciendo que este es un caso excepcional, por lo que es razonable utilizar el manejo de excepciones.
Al abordar sus problemas de rendimiento más directamente, creo que debe mantener un sentido de escala sobre las cosas. Lanzar / atrapar una excepción en estas circunstancias es probable que tome uno del orden de un microsegundo. A medida que avanza el control de flujo, eso es lento , muchas veces más lento que las
if
declaraciones normales , no hay duda al respecto.Al mismo tiempo, tenga en cuenta que lo que está haciendo aquí es leer datos de una red. A 10 megabits por segundo (lento para una red local, pero bastante rápido a medida que van las conexiones a Internet), eso es en el mismo orden que el tiempo para leer un byte de información.
Por supuesto, esa sobrecarga solo se incurre cuando realmente lanzas la excepción también: cuando no se lanza, generalmente hay poca o ninguna sobrecarga (al menos por lo que he visto, la sobrecarga más significativa no es del manejo de excepciones en sí mismo, como la adición de más flujos potenciales de control, haciendo que el código sea más difícil de optimizar para el compilador).
En este caso, cuando se lanza una excepción, sus datos de escritura en el registro. Dada la naturaleza del registro, es muy probable que elimine esa salida tan pronto como la escriba (para asegurarse de que no se pierda). Escribir en el disco es (de nuevo) una operación bastante lenta: necesita un SSD de clase empresarial bastante rápido para llegar incluso al rango de decenas de miles de IOP / segundo. Un disco utilizado para iniciar sesión podría limitarse fácilmente a algo así como cientos de IOP / segundo.
En pocas palabras: hay casos en los que la sobrecarga de manejo de excepciones puede ser significativa, pero es casi seguro que no es uno de ellos.
fuente