ejemplo - Rendimiento de prueba/captura de Java, ¿se recomienda mantener al mínimo lo que está dentro de la cláusula de prueba?
text field java (9)
En su ejemplo aquí, el golpe de rendimiento real es si tanto doSomething () y doAnotherThing () arrojan excepciones. Entrar en un try-block es rápido, hasta que lanza una excepción.
Realmente se trata de cuál es tu situación. Si necesita hacer lo mismo cuando se lanza MyCheckedException de cualquier manera, lo consideraría más legible y más eficiente para tenerlos a ambos en el mismo bloque de prueba, pero si necesita manejar las dos situaciones diferentes de manera diferente, por supuesto tiene más sentido separarlos.
Editar: Leí el final de su comentario, suponiendo que maneje de la misma manera, en cuyo caso los pondría a ambos en el mismo bloque de prueba.
Teniendo en cuenta que tienes un código como este:
doSomething() // this method may throw a checked a exception
//do some assignements calculations
doAnotherThing() //this method may also throw the same type of checked exception
//more calls to methods and calculations, all throwing the same kind of exceptions.
Ahora sé, de hecho hay un golpe de rendimiento al construir la excepción, específicamente desenrollando la pila. Y también he leído varios artículos que apuntan a un pequeño golpe de rendimiento al ingresar bloques de prueba / captura, pero ninguno de los artículos parece concluir nada.
Mi pregunta es, ¿se recomienda mantener las líneas dentro de la captura de prueba al mínimo? Es decir, SOLO tiene dentro de la cláusula de prueba las líneas que realmente pueden arrojar la excepción que está capturando. ¿El código dentro de la cláusula try se ejecuta más lento o causa un golpe de rendimiento ?.
Pero lo más importante es cuál es la mejor práctica / solución más legible considerando hacer esto:
try {
doSomething() // this method may throw a checked a exception
//do some assignements calculations
doAnotherThing() //this method may also throw the same type of checked exception
//more calls to methods and calculations, all throwing the same kind of exceptions.
}
catch (MyCheckedException e) {
//handle it
}
o:
try {
doSomething() // this method may throw a checked a exception
}
catch (MyCheckedException e) {
//Store my exception in a Map (this is all running in a loop and I want it to continue running, but I also want to know which loops didn''t complete and why)
continue;
}
//do some assignements calculations
try {
doAnotherThing() // this method may throw a checked a exception
}
catch (MyCheckedException e) {
//Store my exception in a Map (this is all running in a loop and I want it to continue running, but I also want to know which loops didn''t complete and why)
continue;
}
Esto está considerando que manejará TODAS estas excepciones marcadas exactamente de la misma manera, por supuesto.
Hay una sobrecarga para cada bloque de excepción. Por lo tanto, desea maximizar la cantidad de tiempo que permanece en un bloque.
Sin embargo, también debes considerar la diferencia en semántica. En su primer ejemplo, si doSomething()
arroja una excepción, doAnotherThing()
no se ejecutará. En el segundo ejemplo (suponiendo que el manejador de captura no retorna), se doAnotherThing()
.
Mantener el número de bloqueos de prueba / captura al mínimo mejorará ligeramente el rendimiento, pero mover el trabajo no marcará la diferencia, excepto por el trabajo que se omitirá debido a una excepción lanzada.
No estoy seguro de cuál es más lento, pero no olvide que un bloqueo de try
es flujo de control. Debe hacer que el flujo de control coincida con lo que está tratando de lograr. Para mí, la elección entre
try {
// op 1.
// op 2.
/ ...
// op n.
}
catch ( MyCheckedException error )
{
// handle any `MyException` in op 1, 2 ... n.
}
y bloques de catch
separados para cada uno es principalmente una decisión de si deseo hacer un manejo diferente para cada operación, seguir ejecutando hasta que opere independientemente de los errores o intentar ejecutarlos todos y fallar en el primer error.
Escriba un código limpio y legible, y luego busque cuellos de botella. Si los experimentos existentes no pueden concluir con las pautas básicas, entonces sospecho que de todos modos no encontrará los cuellos de botella allí.
Su código solo debe manejar las excepciones sobre las que puede hacer algo, los otros deben volver a lanzarse.
La cantidad de código en el bloque try no causa ralentizaciones, lo que afecta al bloque catch. Pero a menos que intentes escribir un código de alto rendimiento real, no me preocuparía.
Tener try-blocks debería tener básicamente un efecto de rendimiento cero en cualquier JVM decente. El verdadero éxito llega cuando se lanza una excepción.
Puede leer este artículo para hacerse una idea de cómo la JVM implementa el manejo de excepciones en bytecode: crea "tablas de excepciones" que mapean regiones de código para atrapar / finalmente bloquear, entonces:
- Bytecode para un try-block es el mismo que para un bloque {} estándar
- El único costo adicional en el caso que no arroja es el de tener la "tabla de excepción" cargada en la memoria.
Por supuesto, cuando se lanza una excepción, hay mucho trabajo en la pila, por lo que va a tener un costo. De todos modos, no es tan malo como con SEH (excepciones .NET).
Las excepciones cuestan mucho porque cada vez que se lanza una excepción, el rastreo de pila debe crearse y rellenarse.
Imagine una operación de transferencia de saldos que falla en el 1% de los casos debido a la falta de fondos. Incluso con esta tasa relativamente baja de fallas, el rendimiento puede verse gravemente afectado.
Vea el código fuente y los resultados del benchmark aquí .
No estoy seguro de que dentro del bloque try
el rendimiento sea lento, pero lo que sí sé es que el rendimiento de ex.getStackTrace()
es muy lento porque revela toda la pila de comandos y debes tener cuidado con eso.
¿Se recomienda mantener las líneas dentro de la captura de prueba al mínimo?
No. No puedo imaginar cómo podría pensar que la longitud de un bloque de try
o incluso de cualquier bloque puede tener un impacto en el rendimiento.
¿El código dentro de la cláusula try se ejecuta más lento o causa un golpe de rendimiento ?.
No.
Como observó, las excepciones solo incurren en costos de rendimiento cuando se lanzan.
Si le preocupa el rendimiento de "probar", ¿seguramente lo que debe hacer es mantener el código dentro de un máximo?