gpt4 book ai didi

java - Java 中的 try-catch block 应该有多深?

转载 作者:行者123 更新时间:2023-11-30 04:14:57 25 4
gpt4 key购买 nike

由于我的新工作,我在 Java 方面做了很多工作,现在我正在研究一些微小的细节。显然,Java 代码在某种程度上与异常有关。我想知道:

调用堆栈对 try-catch block 的性能影响很大吗? IE。我是否应该避免尝试调用一个函数......并且走得太深?

我读到 try-catch block 仅影响异常时的性能。然而,它们冒泡多远有关系吗?

最佳答案

我们来测量一下,好吗?

package tools.bench;

import java.math.BigDecimal;

public abstract class Benchmark {

final String name;

public Benchmark(String name) {
this.name = name;
}

abstract int run(int iterations) throws Throwable;

private BigDecimal time() {
try {
int nextI = 1;
int i;
long duration;
do {
i = nextI;
long start = System.nanoTime();
run(i);
duration = System.nanoTime() - start;
nextI = (i << 1) | 1;
} while (duration < 1000000000 && nextI > 0);
return new BigDecimal((duration) * 1000 / i).movePointLeft(3);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}

@Override
public String toString() {
return name + "\t" + time() + " ns";
}

enum ExceptionStrategy {
none {
@Override void run() {
// do nothing
}
},
normal {
@Override void run() {
throw new RuntimeException();
}
},
withoutStackTrace {
@Override void run() {
throw new RuntimeException() {
public synchronized Throwable fillInStackTrace() {
return this;
};
};
}
};

abstract void run();
}

private static Benchmark tryBenchmark(final int depth, final ExceptionStrategy strat) {
return new Benchmark("try, depth = " + depth + ", " + strat) {
@Override int run(int iterations) {
int x = 0;
for (int i = 1; i < iterations; i++) {
try {
x += recurseAndThrow(depth);
} catch (Exception e) {
x++;
}
}
return x;
}

private int recurseAndThrow(int i) {
if (i > 0) {
return recurseAndThrow(i - 1) + 1;
} else {
strat.run();
return 0;
}
}
};
}

public static void main(String[] args) throws Exception {
int[] depths = {1, 10, 100, 1000, 10000};
for (int depth : depths) {
for (ExceptionStrategy strat : ExceptionStrategy.values()) {
System.out.println(tryBenchmark(depth, strat));
}
}
}
}

在我的(相当过时的)笔记本上,打印着:

try, depth = 1, none                           5.153 ns
try, depth = 1, normal 3374.113 ns
try, depth = 1, withoutStackTrace 602.570 ns
try, depth = 10, none 59.019 ns
try, depth = 10, normal 9064.392 ns
try, depth = 10, withoutStackTrace 3528.987 ns
try, depth = 100, none 604.828 ns
try, depth = 100, normal 49387.143 ns
try, depth = 100, withoutStackTrace 27968.674 ns
try, depth = 1000, none 5388.270 ns
try, depth = 1000, normal 457158.668 ns
try, depth = 1000, withoutStackTrace 271881.336 ns
try, depth = 10000, none 69793.242 ns
try, depth = 10000, normal 2895133.943 ns
try, depth = 10000, withoutStackTrace 2728533.381 ns

显然,具体结果会因您的硬件、JVM 实现和配置而异。然而,总体模式可能保持不变。

结论:

  • try 语句本身产生的开销可以忽略不计。
  • 抛出异常并展开调用堆栈会产生与堆栈大小(或要展开的堆栈量)成线性关系的开销。
    • 对于实际应用程序的堆栈大小(假设有 100 个堆栈帧),该开销约为 50 微秒,即 0.00005 秒。
    • 通过抛出没有堆栈跟踪的异常可以在一定程度上减少开销

建议:

关于java - Java 中的 try-catch block 应该有多深?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18613199/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com