【发布时间】:2014-07-02 09:51:17
【问题描述】:
为什么添加方法级断点会对调试模式下的程序性能产生如此负面的影响?
举以下(有些人为的)例子:
public static void main(String[] args) {
long start = System.currentTimeMillis();
for(int a = 0; a <Integer.MAX_VALUE; a++) {
long v = a * a;
if(v == 100) {
doSomething();
}
}
System.out.println("Time: " + (System.currentTimeMillis() - start) + " ms");
}
private static void doSomething() { //*** BREAKPOINT 2
System.out.println("done something"); //*** BREAKPOINT 1
}
这样的表现大概是:
- 不在调试中:4.5 秒
- 调试,断点1:6.0秒
- 调试,断点 2:47.0 秒
发生了什么事?方法级调试给我们带来了哪些普通的调试所没有的好处?
谢谢!
编辑
时间只是近似值,包括我对断点做出反应并继续应用程序所需的时间(看起来大约是 1 秒)。
我很欣赏 System.currentTimeMillis() 并非 100% 准确,但是多次测试的结果是一致的,而且性能差异很大!事实上,添加方法级断点会导致 IntelliJ 发出警告,指出它会对性能产生影响。
【问题讨论】:
-
等等,你是在断点活动的情况下测量性能吗?在这种情况下,我认为您的应用程序的性能取决于您推进调试器的反应速度,除非我不理解您的问题。
-
这是真的,它解释了不调试和使用正常断点调试之间的 1.5 秒。不过,我对 40 秒的跳跃很感兴趣 - 我将编辑问题以使其清楚!
-
这在多次测试中是否一致?是不是你的 IDE 在进入 Debug 透视图时反应较慢,打开调试的类,突出显示行,显示堆栈,...
-
@staticx 它可能会波动,但肯定不会达到秒级。如您所见,OP 仅在开始和结束时测量时间,因此没有累积错误。
-
@staticx 我非常了解计时以及它如何影响事物。如果这是一个适当的实验——那将是一个错误。我要说的是,这里呈现的时差是肉眼可见的。即使你完全去掉了千分尺,只用手表计时,它也会得到类似的结果。 nano和millies之间的时间差异并没有那么大,坦率地说,我从未见过超过1/500周期的波动(更不用说像你建议的1/50),它需要一个非常糟糕的情况像那样发生。