Fab*_*ler 6 java eclipse debugging performance intellij-idea
更新:虽然我一年多前就问过这个问题,但仍然没有答案。出于好奇,我用 IntelliJ IDEA 重现了今天在 Eclipse 中观察到的问题。
我最近正在调试一个类,其中包含执行大量操作的阻塞且长时间运行的方法。有趣的是,调试速度有时变化很大。我有一种感觉,速度与不同的调试方法(Step Into、Step Over、Step Return、Resume)相关。
我写了一个最小的例子,可以在以下课程的帮助下重现和衡量我的感受:

测试类只是测量计数器在“长时间运行”操作中递增的频率。为了测试假设,我在调用之前设置了一个断点来停止程序longRunningOperation,然后应用不同的调试方法。
给定显示的断点,我使用不同的调试策略以不特定的顺序执行了多次重复测量(以最大限度地减少系统错误的可能性):
| #| 运行| 不带断点 | 简历 | 结束 | 进入+返回| 进入+简历 | |----------|----------|----------------|-------- ---|----------|-------------|----------| | 1 | 863342711 | 862587196 | 872204399 | 14722473 | 12550871 | 870687830 | | 2 | 868929379 | 864245840 | 872166407 | 14139145 | 12487883 | 870626416 | | 3 | 865544040 | 852645848 | 872988659 | 14352193 | 12459235 | 12459235 871062770 | | 4 | 868100763 | 863198685 | 867518560 | 12261625 | 14696307 | 871365658 | | 5 | 865157647 | 866257267 | 862671156 | 12524087 | 14620150 | 868541690 | | 6 | 865348827 | 863449576 | 864416490 | 14410005 | 14592026 | 868784314 | | 7 | 866957323 | 865379147 | 873324542 | 14326951 | 12648924 | 868621635 | | 8 | 860129057 | 868993541 | 867785706 | 14434965 | 14380032 | 875011465 | | 9 | 865961737 | 857872085 | 871137322 | 12440011 | 12262172 | 871357411 | | 10 | 10 865517465 | 864911063 | 865109071 | 14544906 | 12391397 | 871574154 | | | | | | | | | | 平均 | 865498895 | 862954025 | 868932231 | 13815636 | 13308900 | 870763334 | | 偏差| 0,00% | 0,29% | -0,40% | 98,40% | 98,46% | -0,61% |
每个调试策略执行 10 次,结果System.out.println(res)显示在相应的列中。该Mean行包含每个策略 10 次测量的平均值。该行包含与运行Deviation策略的相对偏差。结果是使用 IntelliJ IDEA 获得的,但在 Eclipse 中类似。
结果表明,在调试期间使用step over或step into + step out执行长时间运行的方法比其他选项慢10 倍以上。但我无法解释为什么会发生这种情况?调试器在内部做了什么来产生这样的行为?
注意:我在 Windows 10 上使用 Java 8 和 IntelliJ IDEA 2016.2 执行了测量。
为了在您的机器上重现该行为,我已将小类放入Gist中。
我仍然遇到同样的问题,我相信这并不是实现,而是一般的 Java 调试(如果这是实现的错误,IntelliJ 必须同样糟糕地实现它,并且两个 IDE 都实现它,这对我来说似乎不太可能) 。
我在 SO 上发现了这篇文章,这让我怀疑当单步执行代码时,Java 永远不会一步步离开未优化的解释字节码。当继续时,我相信它会检查它可以运行到哪一点,并以优化的方法执行此操作,从而使其速度更快。
但请注意,这只是我个人的怀疑,我没有任何事实可以证明这一点(除了这些操作的执行情况)。
然而,我确实找到了这个问题的“解决方案”。即:Run to Line.
此功能会将代码运行到光标当前所在的行。因此,它似乎与在该行中添加断点、继续执行然后再次删除断点具有相同的效果。Ctrl+R通过这种方法,人们可以通过将光标放在下一行并点击(默认快捷键)来“跳过”一行。
| 归档时间: |
|
| 查看次数: |
2899 次 |
| 最近记录: |