上下文
因此,我通过向其添加一些方法引用来处理与How slow are Java exceptions?相关的代码。修改后的代码如下
/**
* [https://stackoverflow.com/questions/299068/how-slow-are-java-exceptions]
*
* The original code is credited to
* [https://stackoverflow.com/users/15809/mecki] &
* [https://stackoverflow.com/users/581994/hot-licks]
*
*/
public class ThrowableCost {
int value;
public int getValue() {
return value;
}
public void reset() {
value = 0;
}
// This one will regularly throw one
public void method3(int i) {
value = ((value + i) / i) << 1;
// i & 1 is equally fast to calculate as i & 0xFFFFFFF; it is both
// an AND operation between two integers. The size of the number plays
// no role. AND on 32 BIT always ANDs all 32 bits
if ((i & 0x1) == 1) {
throw new RuntimeException();
}
}
// Similar to {@link #method3} but not throw the newly created exceptions.
public void method5(int i) {
value = ((value + i) / i) << 1;
// i & 1 is equally fast to calculate as i & 0xFFFFFFF; it is both
// an AND operation between two integers. The size of the number plays
// no role. AND on 32 BIT always ANDs all 32 bits
if ((i & 0x1) == 1) {
new RuntimeException();
}
}
private RuntimeException e = new RuntimeException();
// Similar to {@link #method3} but throw the pre-created exception.
public void method6(int i) {
value = ((value + i) / i) << 1;
// i & 1 is equally fast to calculate as i & 0xFFFFFFF; it is both
// an AND operation between two integers. The size of the number plays
// no role. AND on 32 BIT always ANDs all 32 bits
if ((i & 0x1) == 1) {
throw e;
}
}
public static void main(String[] args) {
System.out.println("Running...");
ThrowableCost t = new ThrowableCost();
invokeWithTryCatch(t, t::method3, "method3");
invokeWithTryCatch(t, t::method5, "method5");
invokeWithTryCatch(t, t::method6, "method6");
System.out.println("Done!");
}
private static void invokeWithTryCatch(ThrowableCost t, Consumer c, String label) {
long l = System.currentTimeMillis();
int i;
t.reset();
for (i = 1; i < 100000000; i++) {
try {
c.accept(i);
} catch (Exception e) {
// Do nothing here, as we will get here
}
}
l = System.currentTimeMillis() - l;
System.out.println(String.format("%s took %d ms, result was %d", label, l, t.getValue()));
}
}
/**
* Similar to {@link java.util.function.Consumer} but avoid auto-boxing in our case.
*/
interface Consumer{
void accept(int i);
}
输出为
Running...
method3 took 30088 ms, result was 2
method5 took 29948 ms, result was 2
method6 took 6298 ms, result was 2
Done!
您可以看到method6
的执行时间约为6000毫秒。
但是,如果我
method6
(通过注释掉其他invokeWithTryCatch
)或method6
的顺序调用invokeWithTryCatch
或method6
而不是t
内部的c
调用了invokeWithTryCatch
然后method6
的执行要短得多(即:大约700毫秒)
问题
为什么用这种方法invokeWithTryCatch
的顺序会影响method6
的执行时间?
注意 我尝试过同时使用JDK8和JDK11。