我注意到,当我使用条件断点进行调试时,执行速度会显著减慢。我知道这一点已经有一段时间了,现在想知道为什么。到底是什么原因导致执行如此缓慢?我知道正在添加条件,但是如果我自己添加条件,我不会减慢执行速度。
例如,假设我们有以下代码。假设我们添加了一个条件断点a=i
。让我们将条件设置为i==10000。
public class Main {
public static void main(String[] args) {
int a = 0;
for (int i = 0; i<100000; i++) {
a = i; //put breakpoint here (if i == 10000)
}
System.out.println("Done! a=" + a);
}
}
现在,让我们自己编写条件。
public class Main {
public static void main(String[] args) {
int a = 0;
for (int i = 0; i<100000; i++) {
if (i == 10000)
a = i; //put a NON-conditional breakpoint here
else a = i;
}
System.out.println("Done! a=" + a);
}
}
为什么这两者的运行时间有如此显著的不同?为什么第一个要慢得多?
如果你想知道,我在Linux (Ubuntu)上使用Oracle-JDK-8。我用Eclipse和IntelliJ得到了同样的结果。
实验结果
我在多个IDE上运行了第一个案例,以查看是否存在差异。以下是结果
IntelliJ:
~9秒即命中断点
~90秒完成命中(包括最初的9秒)
Eclipse:
~9秒即命中断点
~90秒完成命中(包括最初的9秒)
Netbeans:
~ 12秒即命中断点
~ 190秒完成命中(包括最初的12秒)
所以IntelliJ和Eclipse差不多,但是Netbeans要慢得多。
第二个示例几乎同时在所有IDE上运行,所以我没有做实验。(但我确实运行了所有三个,以查看是否有延迟,没有一个。)
发布于 2014-07-10 02:28:38
条件断点依赖于解释性的(!)条件的评估,只要命中断点的位置就会执行。
命中断点是快速的:顺序执行流被中断,例如,通过用触发中断的一些代码替换该位置处的指令。但条件的求值必须从内存中获取变量的值并计算结果,这与表达式在编译代码中求值的方式不同。预计会出现相当大的减速。
编译后的表达式产生机器指令(在Java语言中,至少在JIT编译之后),而解释表达式基于抽象语法树(数据结构),例如Equals( Variable( "i" ), Literal( 10000 ))
和下降到该数据结构、获取值("i")和计算操作("==")的代码。
https://stackoverflow.com/questions/24661062
复制相似问题