Pregunta: ¿El manejo de excepciones en Java es realmente lento?
La sabiduría convencional, así como muchos resultados de Google, dicen que la lógica excepcional no debe usarse para el flujo normal de programas en Java. Generalmente se dan dos razones,
- es realmente lento, incluso un orden de magnitud más lento que el código normal (las razones dadas varían),
y
- es complicado porque la gente espera que solo se manejen los errores en un código excepcional.
Esta pregunta es sobre el # 1.
Como ejemplo, esta página describe el manejo de excepciones de Java como "muy lento" y relaciona la lentitud con la creación de la cadena de mensaje de excepción: "esta cadena se usa para crear el objeto de excepción que se lanza. Esto no es rápido". El artículo Manejo efectivo de excepciones en Java dice que "la razón de esto se debe al aspecto de creación de objetos del manejo de excepciones, lo que hace que lanzar excepciones sea inherentemente lento". Otra razón es que la generación de seguimiento de la pila es lo que la ralentiza.
Mi prueba (usando Java 1.6.0_07, Java HotSpot 10.0, en Linux de 32 bits), indica que el manejo de excepciones no es más lento que el código normal. Intenté ejecutar un método en un bucle que ejecuta algún código. Al final del método, uso un booleano para indicar si regresar o tirar . De esta manera, el procesamiento real es el mismo. Intenté ejecutar los métodos en diferentes órdenes y promediar mis tiempos de prueba, pensando que podría haber sido el calentamiento de JVM. En todas mis pruebas, el lanzamiento fue al menos tan rápido como el retorno, si no más rápido (hasta 3.1% más rápido). Estoy completamente abierto a la posibilidad de que mis pruebas fueron incorrectas, pero no he visto nada en el camino del ejemplo de código, comparaciones de prueba o resultados en el último año o dos que muestren que el manejo de excepciones en Java sea realmente lento.
Lo que me llevó por este camino fue una API que necesitaba usar que arrojó excepciones como parte de la lógica de control normal. Quería corregirlos en su uso, pero ahora es posible que no pueda hacerlo. ¿Tendré que elogiarlos por su visión de futuro?
En el documento Manejo eficiente de excepciones de Java en la compilación justo a tiempo , los autores sugieren que la sola presencia de controladores de excepciones, incluso si no se lanzan excepciones, es suficiente para evitar que el compilador JIT optimice el código correctamente, lo que lo ralentiza . Todavía no he probado esta teoría.
fuente
exceptions are, as their name implies, to be used only for exceptional conditions; they should never be used for ordinary control flow
- dando una explicación completa y extensa de por qué. Y él era el tipo que escribió Java lib. Por lo tanto, él es quien define el contrato de API de las clases. Estoy de acuerdo con Bill K en este caso.Respuestas:
Depende de cómo se implementen las excepciones. La forma más simple es usar setjmp y longjmp. Eso significa que todos los registros de la CPU se escriben en la pila (que ya lleva algo de tiempo) y posiblemente se deban crear otros datos ... todo esto ya sucede en la declaración de prueba. La instrucción throw debe desenrollar la pila y restaurar los valores de todos los registros (y otros posibles valores en la VM). Por lo tanto, intentar y lanzar son igualmente lentos, y eso es bastante lento, sin embargo, si no se lanza una excepción, salir del bloque de prueba no toma tiempo en la mayoría de los casos (ya que todo se coloca en la pila que se limpia automáticamente si existe el método).
Sun y otros reconocieron que esto es posiblemente subóptimo y, por supuesto, las máquinas virtuales se vuelven cada vez más rápidas con el tiempo. Hay otra forma de implementar excepciones, lo que hace que el intento sea rápido como un rayo (en realidad, no pasa nada para intentarlo en general, todo lo que debe suceder ya está hecho cuando la clase es cargada por la VM) y hace que el lanzamiento no sea tan lento . No sé qué JVM usa esta nueva y mejor técnica ...
... pero ¿está escribiendo en Java para que su código posterior solo se ejecute en una JVM en un sistema específico? Dado que si alguna vez puede ejecutarse en cualquier otra plataforma o cualquier otra versión de JVM (posiblemente de cualquier otro proveedor), ¿quién dice que también usan la implementación rápida? El rápido es más complicado que el lento y no es fácilmente posible en todos los sistemas. ¿Quieres permanecer portátil? Entonces no confíes en que las excepciones sean rápidas.
También hace una gran diferencia lo que haces dentro de un bloque de prueba. Si abre un bloque de prueba y nunca llama a ningún método desde este bloque de prueba, el bloque de prueba será ultra rápido, ya que el JIT puede tratar un lanzamiento como un simple goto. No necesita guardar el estado de la pila ni necesita desenrollar la pila si se produce una excepción (solo necesita saltar a los controladores de captura). Sin embargo, esto no es lo que generalmente haces. Por lo general, abre un bloque de prueba y luego llama a un método que podría generar una excepción, ¿verdad? E incluso si solo usa el bloque try dentro de su método, ¿qué tipo de método será este, que no llame a ningún otro método? ¿Solo calculará un número? Entonces, ¿para qué necesitas excepciones? Hay formas mucho más elegantes de regular el flujo del programa. Para casi cualquier otra cosa que no sea matemática simple,
Vea el siguiente código de prueba:
Resultado:
La desaceleración del bloque de prueba es demasiado pequeña para descartar factores de confusión como los procesos en segundo plano. ¡Pero el bloque de captura mató todo y lo hizo 66 veces más lento!
Como dije, el resultado no será tan malo si pones try / catch y arrojas todo dentro del mismo método (method3), pero esta es una optimización JIT especial en la que no confiaría. E incluso cuando se utiliza esta optimización, el lanzamiento sigue siendo bastante lento. Así que no sé qué estás tratando de hacer aquí, pero definitivamente hay una mejor manera de hacerlo que usando try / catch / throw.
fuente
nanoTime()
requiere Java 1.5 y solo tenía Java 1.4 disponible en el sistema que utilicé para escribir el código anterior. Además, no juega un papel muy importante en la práctica. La única diferencia entre los dos es que uno es nanosegundos y el otro milisegundos y esonanoTime
no está influenciado por las manipulaciones del reloj (que son irrelevantes, a menos que usted o el proceso del sistema modifique el reloj del sistema exactamente en el momento en que se ejecuta el código de prueba). En general, tiene razón, sin embargo,nanoTime
es , por supuesto, la mejor opción.try
bloque, pero nothrow
. Suthrow
prueba arroja excepciones el 50% del tiempo que pasa por eltry
. Esa es claramente una situación en la que el fracaso no es excepcional . Reducir eso a solo un 10% reduce masivamente el impacto en el rendimiento. El problema con este tipo de prueba es que alienta a las personas a dejar de usar excepciones por completo. El uso de excepciones, para un manejo de casos excepcional, funciona mucho mejor de lo que muestra su prueba.return
. Deja un método en algún lugar en el medio del cuerpo, tal vez incluso en el medio de una operación (que hasta ahora solo se ha completado en un 50%) y elcatch
bloque puede tener 20 cuadros de pila hacia arriba (un método tiene untry
bloque, llamando al método1, que llama a method2, que llama a mehtod3, ..., y en method20 en medio de una operación se produce una excepción). La pila debe desenrollarse 20 cuadros hacia arriba, todas las operaciones sin terminar deben deshacerse (las operaciones no deben realizarse a la mitad) y los registros de la CPU deben estar limpios. Todo esto consume tiempo.FYI, extendí el experimento que hizo Mecki:
Los primeros 3 son los mismos que los de Mecki (mi computadora portátil es obviamente más lenta).
method4 es idéntico a method3, excepto que crea un en
new Integer(1)
lugar de hacerthrow new Exception()
.method5 es como method3 excepto que crea el
new Exception()
sin tirarlo.method6 es como method3 excepto que arroja una excepción pre-creada (una variable de instancia) en lugar de crear una nueva.
En Java, gran parte del gasto de lanzar una excepción es el tiempo dedicado a recopilar el seguimiento de la pila, que ocurre cuando se crea el objeto de excepción. El costo real de lanzar la excepción, aunque grande, es considerablemente menor que el costo de crear la excepción.
fuente
Aleksey Shipilëv hizo un análisis muy exhaustivo en el que compara las excepciones de Java en varias combinaciones de condiciones:
También los compara con el desempeño de verificar un código de error en varios niveles de frecuencia de error.
Las conclusiones (citadas textualmente de su publicación) fueron:
Excepciones verdaderamente excepcionales son maravillosamente efectivas. Si los usa según lo diseñado, y solo comunica los casos verdaderamente excepcionales entre la abrumadora cantidad de casos no excepcionales manejados por código regular, entonces el uso de excepciones es la ganancia de rendimiento.
Los costos de rendimiento de las excepciones tienen dos componentes principales: la construcción del seguimiento de la pila cuando se crea una instancia de Exception y el desenrollado de la pila durante el lanzamiento de la Excepción.
Los costos de construcción de seguimiento de pila son proporcionales a la profundidad de pila en el momento de la instanciación de excepción. Eso ya es malo porque ¿quién en la Tierra conoce la profundidad de la pila a la que se llamaría este método de lanzamiento? Incluso si desactiva la generación de rastreo de pila y / o almacena en caché las excepciones, solo puede deshacerse de esta parte del costo de rendimiento.
Los costos de eliminación de la pila dependen de la suerte que tengamos al acercar el controlador de excepciones en el código compilado. La estructuración cuidadosa del código para evitar la búsqueda de controladores de excepciones profundas probablemente nos esté ayudando a tener más suerte.
Si eliminamos ambos efectos, el costo de rendimiento de las excepciones es el de la sucursal local. No importa cuán hermoso suene, eso no significa que deba usar Excepciones como el flujo de control habitual, porque en ese caso está a merced de optimizar el compilador. Solo debe usarlos en casos verdaderamente excepcionales, donde la frecuencia de excepción amortiza el posible costo desafortunado de aumentar la excepción real.
La regla general optimista parece ser una frecuencia de 10 ^ -4 para excepciones es suficientemente excepcional. Eso, por supuesto, depende de los pesos pesados de las excepciones en sí, las acciones exactas tomadas en los manejadores de excepciones, etc.
El resultado es que cuando no se lanza una excepción, no paga un costo, por lo que cuando la condición excepcional es lo suficientemente rara, el manejo de excepciones es más rápido que usarlo
if
cada vez. Vale la pena leer la publicación completa.fuente
Mi respuesta, desafortunadamente, es demasiado larga para publicar aquí. Así que permítanme resumir aquí y remitirlos a http://www.fuwjax.com/how-slow-are-java-exceptions/ para los detalles arenosos.
La verdadera pregunta aquí no es "¿Qué tan lentos son las 'fallas reportadas como excepciones' en comparación con el 'código que nunca falla'?" como la respuesta aceptada podría hacerte creer. En cambio, la pregunta debería ser "¿Qué tan lentas son las 'fallas reportadas como excepciones' en comparación con las fallas reportadas de otras maneras?" En general, las otras dos formas de informar fallas son valores centinela o envoltorios de resultados.
Los valores centinela son un intento de devolver una clase en caso de éxito y otra en caso de fracaso. Puedes pensarlo casi como devolver una excepción en lugar de lanzar una. Esto requiere una clase primaria compartida con el objeto de éxito y luego hacer una comprobación de "instancia de" y un par de conversiones para obtener la información de éxito o fracaso.
Resulta que a riesgo de la seguridad de tipo, los valores de Sentinel son más rápidos que las excepciones, pero solo por un factor de aproximadamente 2x. Ahora, eso puede parecer mucho, pero ese 2x solo cubre el costo de la diferencia de implementación. En la práctica, el factor es mucho más bajo ya que nuestros métodos que pueden fallar son mucho más interesantes que algunos operadores aritméticos como en el código de muestra en otra parte de esta página.
Los Envoltorios de resultados, por otro lado, no sacrifican la seguridad de tipo en absoluto. Envuelven la información de éxito y fracaso en una sola clase. Entonces, en lugar de "instanceof", proporcionan un "isSuccess ()" y captadores para los objetos de éxito y error. Sin embargo, los objetos resultantes son aproximadamente 2 veces más lentos que usar excepciones. Resulta que crear un nuevo objeto contenedor cada vez es mucho más costoso que lanzar una excepción a veces.
Además de eso, las excepciones son el lenguaje proporcionado para indicar que un método puede fallar. No hay otra manera de saber, solo desde la API, qué métodos se espera que funcionen siempre (en su mayoría) y cuáles se espera que reporten fallas.
Las excepciones son más seguras que los centinelas, más rápidas que los objetos resultantes y menos sorprendentes que cualquiera de ellas. No estoy sugiriendo que try / catch reemplace if / else, pero las excepciones son la forma correcta de informar un fallo, incluso en la lógica empresarial.
Dicho esto, me gustaría señalar que las dos formas más frecuentes de impactar sustancialmente el rendimiento que he encontrado son crear objetos innecesarios y bucles anidados. Si tiene la opción de crear una excepción o no crear una excepción, no cree la excepción. Si tiene la opción de crear una excepción a veces o crear otro objeto todo el tiempo, cree la excepción.
fuente
He ampliado las respuestas dadas por @Mecki y @incarnate , sin el relleno de stacktrace para Java
Con Java 7+, podemos usar
Throwable(String message, Throwable cause, boolean enableSuppression,boolean writableStackTrace)
. Pero para Java6, vea mi respuesta a esta preguntaSalida con Java 1.6.0_45, en Core i7, 8 GB de RAM:
Entonces, los métodos que devuelven valores son más rápidos, en comparación con los métodos que arrojan excepciones. En mi humilde opinión, no podemos diseñar una API clara simplemente usando tipos de retorno para los flujos de éxito y error. Los métodos que arrojan excepciones sin stacktrace son 4-5 veces más rápidos que las excepciones normales.
Editar: NoStackTraceThrowable.java Gracias @Greg
fuente
public class NoStackTraceThrowable extends Throwable { public NoStackTraceThrowable() { super("my special throwable", null, false, false); } }
With Java 7+, we can use
pero luego escribiste,Output with Java 1.6.0_45,
así que este es el resultado de Java 6 o 7?Throwable
constructor que tieneboolean writableStackTrace
arg. Pero eso no está presente en Java 6 y versiones posteriores. Es por eso que he dado una implementación personalizada para Java 6 y versiones posteriores. Entonces, el código anterior es para Java 6 y siguientes. Lea atentamente la primera línea del segundo párrafo.Optional
o algo similar llegó un poco tarde a Java. Antes de eso también utilizamos objetos de contenedor con banderas de éxito / error. Pero parece ser un poco pirateado y no me parece natural.Hace un tiempo escribí una clase para probar el rendimiento relativo de convertir cadenas a ints usando dos enfoques: (1) llamar a Integer.parseInt () y capturar la excepción, o (2) hacer coincidir la cadena con una expresión regular y llamar a parseInt () solo si el partido tiene éxito. Utilicé la expresión regular de la manera más eficiente que pude (es decir, creando los objetos Pattern y Matcher antes de intervenir el bucle), y no imprimí ni guardé los stacktraces de las excepciones.
Para una lista de diez mil cadenas, si todos fueran números válidos, el enfoque parseInt () era cuatro veces más rápido que el enfoque de expresiones regulares. Pero si solo el 80% de las cadenas eran válidas, la expresión regular era dos veces más rápida que parseInt (). Y si el 20% era válido, lo que significa que la excepción fue lanzada y capturada el 80% del tiempo, la expresión regular fue aproximadamente veinte veces más rápida que parseInt ().
Me sorprendió el resultado, considerando que el enfoque regex procesa cadenas válidas dos veces: una para el partido y otra vez para parseInt (). Pero lanzar y atrapar excepciones más que compensó eso. No es probable que este tipo de situación ocurra con mucha frecuencia en el mundo real, pero si lo hace, definitivamente no debe usar la técnica de captura de excepciones. Pero si solo está validando la entrada del usuario o algo así, utilice el enfoque parseInt ().
fuente
Integer.ParseInt()
) y espero que la mayoría de las veces la entrada del usuario sea correcta, por lo que para mi caso de uso parece que tomar el golpe de excepción ocasional es el camino a seguir. .Creo que el primer artículo se refiere al acto de atravesar la pila de llamadas y crear un seguimiento de la pila como la parte costosa, y aunque el segundo artículo no lo dice, creo que esa es la parte más costosa de la creación de objetos. John Rose tiene un artículo donde describe diferentes técnicas para acelerar las excepciones. . (Preasignación y reutilización de una excepción, excepciones sin trazas de pila, etc.)
Pero aún así, creo que esto debería considerarse solo un mal necesario, un último recurso. La razón de John para hacer esto es emular características en otros idiomas que (todavía) no están disponibles en la JVM. NO debe acostumbrarse a usar excepciones para el flujo de control. ¡Especialmente no por razones de rendimiento! Como usted mismo menciona en el n. ° 2, corre el riesgo de enmascarar errores graves en su código de esta manera, y será más difícil de mantener para los nuevos programadores.
Los microbenchmarks en Java son sorprendentemente difíciles de acertar (me han dicho), especialmente cuando entras en territorio JIT, por lo que realmente dudo que usar excepciones sea más rápido que el "retorno" en la vida real. Por ejemplo, sospecho que tienes entre 2 y 5 cuadros de pila en tu prueba. Ahora imagine que su código será invocado por un componente JSF implementado por JBoss. Ahora puede tener un seguimiento de pila que tiene varias páginas.
¿Quizás podrías publicar tu código de prueba?
fuente
No sé si estos temas se relacionan, pero una vez quise implementar un truco basado en el seguimiento de la pila del hilo actual: quería descubrir el nombre del método, que desencadenó la creación de instancias dentro de la clase instanciada (sí, la idea es una locura, Lo dejé totalmente). Entonces descubrí que las llamadas
Thread.currentThread().getStackTrace()
son extremadamente lentas (debido aldumpThreads
método nativo que usa internamente).Entonces
Throwable
, Java , correspondientemente, tiene un método nativofillInStackTrace
. Creo que elcatch
bloque asesino descrito anteriormente de alguna manera desencadena la ejecución de este método.Pero déjame contarte otra historia ...
En Scala, algunas características funcionales se compilan en JVM utilizando
ControlThrowable
, lo que extiendeThrowable
y anula sufillInStackTrace
de la siguiente manera:Así que adapté la prueba anterior (la cantidad de ciclos disminuye en diez, mi máquina es un poco más lenta :):
Entonces, los resultados son:
Verá, la única diferencia entre
method3
ymethod4
es que arrojan diferentes tipos de excepciones. Yeap,method4
sigue siendo más lento quemethod1
ymethod2
, pero la diferencia es mucho más aceptable.fuente
He realizado algunas pruebas de rendimiento con JVM 1.5 y el uso de excepciones fue al menos 2 veces más lento. En promedio: el tiempo de ejecución en un método trivialmente pequeño más que triplicado (3x) con excepciones. Un ciclo trivialmente pequeño que tuvo que atrapar la excepción vio un aumento de 2 veces en el tiempo libre.
He visto números similares en el código de producción, así como micro puntos de referencia.
Las excepciones definitivamente NO deben usar para algo que se llama con frecuencia. Lanzar miles de excepciones por segundo causaría un enorme cuello de botella.
Por ejemplo, usar "Integer.ParseInt (...)" para encontrar todos los valores incorrectos en un archivo de texto muy grande, muy mala idea. (He visto este método de utilidad matar el rendimiento en el código de producción)
Usar una excepción para informar un valor incorrecto en un formulario de GUI del usuario, probablemente no sea tan malo desde el punto de vista del rendimiento.
Si es o no una buena práctica de diseño, seguiría la regla: si el error es normal / esperado, entonces use un valor de retorno. Si es anormal, use una excepción. Por ejemplo: al leer las entradas del usuario, los valores incorrectos son normales: use un código de error. Al pasar un valor a una función de utilidad interna, los valores incorrectos se deben filtrar llamando al código; use una excepción.
fuente
El rendimiento de excepción en Java y C # deja mucho que desear.
Como programadores, esto nos obliga a vivir según la regla "las excepciones deben ser infrecuentes", simplemente por razones prácticas de rendimiento.
Sin embargo, como informáticos, debemos rebelarnos contra este estado problemático. La persona que crea una función a menudo no tiene idea de con qué frecuencia se llamará o si es más probable que tenga éxito o fracase. Solo la persona que llama tiene esta información. Intentar evitar excepciones conduce a idoms de API poco claros donde en algunos casos solo tenemos versiones de excepción limpias pero lentas, y en otros casos tenemos errores de valor de retorno rápidos pero torpes, y en otros casos terminamos con ambos . El implementador de la biblioteca puede tener que escribir y mantener dos versiones de API, y la persona que llama tiene que decidir cuál de las dos versiones usar en cada situación.
Esto es un desastre. Si las excepciones tuvieran un mejor rendimiento, podríamos evitar estos modismos torpes y usar excepciones, ya que estaban destinadas a ser utilizadas ... como un servicio estructurado de devolución de errores.
Realmente me gustaría ver mecanismos de excepción implementados utilizando técnicas más cercanas a los valores de retorno, para que podamos tener un rendimiento más cercano a los valores de retorno ... ya que esto es a lo que volvemos en el código sensible al rendimiento.
Aquí hay una muestra de código que compara el rendimiento de excepción con el rendimiento de valor de retorno de error.
TestIt clase pública {
}
Y aquí están los resultados:
Verificar y propagar los valores de retorno agrega algún costo en comparación con la llamada nula de línea de base, y ese costo es proporcional a la profundidad de la llamada. A una profundidad de cadena de llamada de 8, la versión de verificación del valor de retorno de error fue aproximadamente un 27% más lenta que la versión de línea de base que no verificó los valores de retorno.
El rendimiento de excepción, en comparación, no es una función de la profundidad de la llamada, sino de la frecuencia de excepción. Sin embargo, la degradación a medida que aumenta la frecuencia de excepción es mucho más dramática. Con solo una frecuencia de error del 25%, el código se ejecutó 24 VECES más lento. Con una frecuencia de error del 100%, la versión de excepción es casi 100 VECES más lenta.
Esto me sugiere que quizás están haciendo las compensaciones incorrectas en nuestras implementaciones de excepción. Las excepciones podrían ser más rápidas, ya sea evitando los costosos pasos de acecho o simplemente convirtiéndolos en una verificación de valor de retorno compatible con el compilador. Hasta que lo hagan, estamos atrapados evitándolos cuando queremos que nuestro código se ejecute rápido.
fuente
HotSpot es bastante capaz de eliminar el código de excepción para las excepciones generadas por el sistema, siempre que todo esté en línea. Sin embargo, las excepciones creadas explícitamente y las que de otro modo no se eliminan pasan mucho tiempo creando el seguimiento de la pila. Anule
fillInStackTrace
para ver cómo esto puede afectar el rendimiento.fuente
Incluso si lanzar una excepción no es lento, sigue siendo una mala idea lanzar excepciones para el flujo normal del programa. Utilizado de esta manera es análogo a un GOTO ...
Sin embargo, supongo que eso realmente no responde la pregunta. Me imagino que la sabiduría "convencional" de lanzar excepciones siendo lenta era cierta en versiones anteriores de Java (<1.4). Crear una excepción requiere que la máquina virtual cree todo el seguimiento de la pila. Mucho ha cambiado desde entonces en la VM para acelerar las cosas y este es probablemente un área que se ha mejorado.
fuente
break
oreturn
, no agoto
.Simplemente compare, digamos, Integer.parseInt con el siguiente método, que solo devuelve un valor predeterminado en el caso de datos no analizables en lugar de generar una excepción:
Siempre que aplique ambos métodos a datos "válidos", ambos funcionarán aproximadamente a la misma velocidad (aunque Integer.parseInt logra manejar datos más complejos). Pero tan pronto como intente analizar datos no válidos (por ejemplo, analizar "abc" 1.000.000 de veces), la diferencia en el rendimiento debería ser esencial.
fuente
La gran publicación sobre el rendimiento de excepción es:
https://shipilev.net/blog/2014/exceptional-performance/
Instanciar vs reutilizar existentes, con seguimiento de pila y sin, etc.
Dependiendo de la profundidad del seguimiento de la pila:
Para otros detalles (incluido el ensamblador x64 de JIT) lea la publicación original del blog.
Eso significa que Hibernate / Spring / etc-EE-shit son lentos debido a las excepciones (xD) y reescribir el flujo de control de la aplicación lejos de las excepciones (reemplazarlo con
continure
/break
y devolverboolean
indicadores como en C desde la llamada al método) mejora el rendimiento de su aplicación 10x-100x , dependiendo de con qué frecuencia los arrojes))fuente
Cambié la respuesta de @Mecki anterior para que el método1 devuelva un booleano y una verificación en el método de llamada, ya que no puede reemplazar una Excepción con nada. Después de dos ejecuciones, el método1 seguía siendo el más rápido o el más rápido que el método2.
Aquí hay una instantánea del código:
y resultados:
Correr 1
Correr 2
fuente
Una excepción es para manejar condiciones inesperadas en tiempo de ejecución solamente.
El uso de una excepción en lugar de una validación simple que se puede hacer en tiempo de compilación retrasará la validación hasta el tiempo de ejecución. Esto a su vez reducirá la eficiencia del programa.
Lanzar una excepción en lugar de usar una simple validación if..else también hará que el código sea complejo de escribir y mantener.
fuente
Mi opinión sobre la velocidad de excepción versus la verificación de datos mediante programación.
Muchas clases tenían convertidor de cadena a valor (escáner / analizador), bibliotecas respetadas y conocidas también;)
generalmente tiene forma
el nombre de la excepción es solo un ejemplo, generalmente no está marcado (tiempo de ejecución), por lo que la declaración de lanzamiento es solo mi imagen
a veces existe una segunda forma:
nunca tirando
Cuando el segundo no esté disponible (o el programador lea menos documentos y use solo el primero), escriba dicho código con expresión regular. Las expresiones regulares son geniales, políticamente correctas, etc.
Con este código, los programadores no tienen el costo de las excepciones. PERO TIENE un costo muy alto comparable de expresiones regulares SIEMPRE versus un pequeño costo de excepción a veces.
Uso casi siempre en ese contexto
sin analizar stacktrace, etc., creo que después de las conferencias de Yours bastante rápido.
No tengas miedo Excepciones
fuente
¿Por qué las excepciones deberían ser más lentas que lo normal?
Mientras no imprima el stacktrace en el terminal, guárdelo en un archivo o algo similar, el bloque catch no hace más trabajo que otros bloques de código. Entonces, no puedo imaginar por qué "throw new my_cool_error ()" debería ser tan lento.
Buena pregunta y espero más información sobre este tema.
fuente