Escenas
Use JMH (marco de prueba de micro-benchmark de Java Microbenchmark Harness) en Java para pruebas de rendimiento y optimización:
Utilice el método anterior para probar si existe una diferencia de rendimiento entre try-catch en Java y fuera del ciclo.
Nota:
Blog:
Temperamento pícaro autoritario blog_CSDN Blog-C#, Architecture Road, Blogger en SpringBoot
lograr
1. ¿Has oído que la ejecución de try-catch en el cuerpo del bucle será muy lenta?
Para verificar la conclusión anterior, haga la siguiente prueba
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import java.util.concurrent.TimeUnit;
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 2,time = 1,timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 5,time = 5,timeUnit = TimeUnit.SECONDS)
@Fork(1)
@State(Scope.Benchmark)
@Threads(100)
public class TryCatchVSCircleTest {
private static final int maxSize = 10000; //测试循环次数
public static void main(String[] args) throws RunnerException {
//启动基准测试
Options opt = new OptionsBuilder()
.include(TryCatchVSCircleTest.class.getSimpleName()) //要导入的测试类
.build();
//执行测试
new Runner(opt).run();
}
@Benchmark
public int innerForeach(){
int count = 0;
for (int i = 0; i < maxSize; i++) {
try{
if(i == maxSize){
throw new Exception("exception");
}
count++;
}catch (Exception e){
e.printStackTrace();
}
}
return count;
}
@Benchmark
public int outerForeach(){
int count = 0;
try{
for (int i = 0; i < maxSize; i++) {
if(i == maxSize){
throw new Exception("exception");
}
count++;
}
}catch (Exception e){
e.printStackTrace();
}
return count;
}
}
Resultados de la prueba
Punto de referencia Modo Cnt Puntuación Error Unidades
TryCatchVSCircleTest.innerForeach avgt 5 13528.011 ± 833.369 ns/op
TryCatchVSCircleTest.outerForeach avgt 5 13645.087 ± 565.900 ns/op
2. Conclusión
En el caso de que no haya anormalidad, obtenemos la conclusión después de eliminar el valor del error:
Casi no hay diferencia en el rendimiento de try-catch si está dentro o fuera del bucle for.
Analizando su bytecode, podemos saber:
Si no hay ningún error en el código, el rendimiento casi no se ve afectado y la lógica de ejecución del código normal es la misma.
Aunque el rendimiento de try-catch dentro o fuera del ciclo es similar, los significados comerciales de sus códigos son completamente diferentes.
El try-catch en el cuerpo del bucle puede continuar ejecutando el bucle después de que ocurra una excepción, mientras que el try-catch fuera del bucle
Por lo general, el ciclo se termina después.
Por lo tanto, cuando decidimos si try-catch debe colocarse dentro o fuera del bucle, no depende del rendimiento (porque el rendimiento es casi el mismo),
En cambio, debería depender del escenario comercial específico.
Por ejemplo, necesitamos procesar un lote de datos, y no importa qué datos de este conjunto de datos tengan un problema, no puede afectar la ejecución normal de otros grupos.
, en este punto podemos colocar el try-catch en el cuerpo del ciclo;
Y cuando necesitamos calcular el valor total de un conjunto de datos, siempre que haya un error en un conjunto de datos, debemos finalizar la ejecución y lanzar una excepción,
En este punto, debemos colocar el intento de captura fuera del bucle para su ejecución.