Visual Studio-条件和残疾断点的运行时影响
-
22-09-2019 - |
题
在花了一点时间想知道为什么我的应用程序在附带的调试器中非常缓慢地运行特定方案之后,我发现这是由于有条件断点(从未满足其状况)。这似乎是合理的,因为CPU会表示断点,并且VS需要在允许执行继续执行之前评估条件。这些过渡必须是昂贵的。
我认为未执行的代码路径中的断点没有运行时影响。
所以我的问题是双重的:
- 是否有任何资源可以量化与有条件断点相关的成本,如果可以的话,可以做些什么来降低其运行时评估成本?
- 是否有与“禁用”断点相关的费用?由残疾人,我的意思是VS用空心圆显示在排水沟中的断点标记。
当然,如果我上面提到的任何内容没有意义,请指出我的方向正确。
解决方案
很难量化有条件断点的成本。使用完全相同的语义来评估条件断点中的表达式,就像将其输入手表或直接窗口一样。这种性质的表达实际上不是在客户端程序中执行的,而是由语言特定表达式评估器处理。实际上不可能以有意义的方式介绍这些类型的评估。
但是,我可以列出一些已知在调试窗口评估中较慢的东西
- 功能调用:它们是您可以做的最慢的事情,因为函数调用需要重新启动调试过程,以便在此过程中进行func评估
- 字符串比较:在引擎盖下,这些回到弹性
对于残疾断点,不影响应用程序的运行。
其他提示
要注意的一件事(我学到了很难的方法)是确保在将变量与值进行比较时,而不是单个=
断点编辑器不会警告您,但是当评估断点时,变量会更改!花了我一段时间与该代码调试!
另外,如果我真的需要有条件的断点来Bebug代码;我将条件添加到代码中,然后添加类似字符串stop =“ there”之类的东西;并在此处放置一个正常的断点 - 我发现代码运行速度更快。
我在这里读到这些断点有硬件支持,因此使用少于某种的条件断点基本上是免费的,但是在此之上,它需要使用更多的软件。 (OTOH,那是针对本地应用程序的,不确定这些新的JIT事物。)
残疾断点应完全影响事物,它们只是在IDE中占有一些内存和GUI资源。
我还注意到有条件的断点很昂贵,并且与您得出了相同的结论。我无法想象有任何理由是残疾断点会导致任何放缓,因为我希望它是唯一的编辑器,如果您需要的话,可以打开断点的快捷方式。
当我处于像您这样的情况下,我做的是做一个主张宏。 (您可以使用 断言 Visual Studio提供的宏,但我不喜欢)。让宏检查您想要的状况,然后致电 Debugbreak 如果失败。在earease或未经检查的应用程序的构建中,请断言无需评估,因此您的代码不会受到影响。
一个简单的断言宏可以看起来像:
#ifdef _DEBUG
#define assert(x)\
do{\
if(!(x)){DebugBreak();}\
}while(0)
#else
#define assert(x)
#endif
并称其为:
assert(pValue != NULL && "A bad parameter was passed to the function");
您可以在调试之前将更多代码放在故障中(例如打印出#X失败的条件,以及/或带有____ -File____和____Line____的行/文件编号,以便您可以双击消息)。您可以使用 OutputDebugstring 甚至检查是否附上调试器 isdebuggerpresent 量身定制您的断言。我还喜欢使用&&字符串格式提供有关特定断言的更多信息。
使用断言时,有几件事要小心。首先,不要将任何必须在宏中运行的代码放在宏中,因为它将在非调试构建中删除。出于相同的原因,请勿放入具有副作用的代码。另外,当不附加调试器时,您不想致电debugbreak(),因为它本质上会引发异常(如果未抓住)将终止应用程序。
尝试将断点放在代码中以测试性能。例如
Stopwatch st = new Stopwatch(); st.Start(); if(my condition) { st.Stop(); Debugger.Break(); }
不,不完全相同,但很近。
否 - 执行程序中不存在禁用断点。为了您的方便,它只是存储在VS元数据中。