シーン
パフォーマンスのテストと最適化には、Java で JMH (Java Microbenchmark Harness マイクロベンチマーク テスト フレームワーク) を使用します。
Java で JMH (Java Microbenchmark Harness マイクロベンチマーク テスト フレームワーク) を使用してパフォーマンス テストと最適化を行う - プログラマーが求めた
上記の方法を使用して、Java 内とループ外の try-catch の間にパフォーマンスの違いがあるかどうかをテストします。
ノート:
ブログ:
横柄なローグ気質 blog_CSDN ブログ - C#、アーキテクチャ ロード、SpringBoot のブロガー
達成
1. ループ本体での try-catch の実行が非常に遅くなるということを聞いたことがありますか?
上記の結論を検証するには、次のテストを実行します。
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;
}
}
試験結果
ベンチマーク モード Cnt スコア エラー単位
TryCatchVSCircleTest.innerForeach avgt 5 13528.011 ± 833.369 ns/op
TryCatchVSCircleTest.outerForeach avgt 5 13645.087 ± 565.900 ns/op
2. 結論
異常がない場合、エラー値を削除した後の結論が得られます。
for ループの内側でも for ループの外側でも、try-catch のパフォーマンスにほとんど違いはありません。
そのバイトコードを分析すると、次のことがわかります。
コードにエラーがなければ、パフォーマンスにはほとんど影響がなく、通常のコードの実行ロジックは同じです。
try-catch のループ内外のパフォーマンスは似ていますが、それらのコードのビジネス上の意味はまったく異なります。
ループ本体内の try-catch は、例外の発生後もループの実行を続行できますが、ループ外の try-catch は実行を継続できます。
通常、ループはその後終了します。
したがって、try-catchをループの内側に置くか外側に置くかは、性能に依存せず(性能はほぼ同じなので)、
代わりに、特定のビジネス シナリオに依存する必要があります。
たとえば、データのバッチを処理する必要がある場合、このデータ セット内のどのデータに問題があるとしても、他のグループの通常の実行に影響を与えることはできません。
, この時点で、try-catch をループ本体に配置できます。
そして、一連のデータの合計値を計算する必要がある場合、一連のデータにエラーがある限り、実行を終了して例外をスローする必要があります。
この時点で、try-catch を実行するループの外に配置する必要があります。