如何在Delphi 6 IDE中防止大量的OutputDebugString()调用降低我的应用程序性能?

8
这种情况在我身上发生过不止一次,导致我浪费了很多时间去追逐一个幽灵。通常情况下,当我调试一些非常困难的与时间相关的代码时,我会添加大量的OutputDebugString()调用,以便能够清楚地了解相关操作的顺序。问题是,Delphi 6 IDE似乎只能处理那么长时间的情况。为了避免一般性(尽可能),我将使用我刚经历的一个具体例子。
我花了几天时间调试我的线程间信号量锁定代码以及我的DirectShow时间戳计算代码,这些都导致了一些非常令人沮丧的问题。在排除了我能想到的每一个错误之后,我仍然有一个Skype的问题,我的应用程序向其发送音频。
大约在10秒钟之后,我说话并听到自己的声音从我用于测试的第二台PC上的Skype中传出来的延迟开始增加。在20-30秒左右,延迟开始呈指数增长,并触发了我检查是否持有关键部分的代码。
幸运的是,当时并不太晚,因为之前经历过这种情况,我决定停止不断地追踪,并关闭了大部分的OutputDebugString()。幸好,我大多数都包裹在条件编译定义中,所以很容易做到。我一旦这样做,问题就消失了,结果证明我的代码是正常工作的。
看起来Delphi 6 IDE在OutputDebugstring()流量超过某个阈值时会变得非常缓慢。也许只是添加字符串到事件日志调试器窗格的任务,该窗格保存所有OutputDebugString()报告。我不知道,但当TMemo或类似控件开始包含太多字符串时,我也遇到过类似的问题。
你们中间有什么方法可以防止这种情况发生吗?是否有一种通过某种方法调用清除事件日志或至少限制其大小的方式?此外,你使用什么技术,如条件定义、IDE插件或其他方式来应对这种情况?

1
请点击此处查看哪个日志库更好 - LU RD
@LURD。谢谢!关于日志记录工具的概述文章写得很好。 - Robert Oschler
4个回答

4

我以前在Delphi 2007中也遇到了类似的问题。在IDE中禁用事件查看,改用SysinternalsDebugView


我有DebugView,但我不知道你可以禁用事件查看。我会看看Delphi6是否有这个选项,谢谢。 - Robert Oschler
当时有人告诉我,慢的原因是由于在事件日志中使用了StringGrid(现在改为VirtualStringTree)。这里是我特定问题的线程缓存,当时在Emb..论坛上。 - Sertac Akyuz

2
我很少使用OutputDebugString。我发现在集成开发环境中分析输出很难,而且要花费额外的精力来保持多个运行的几组数据。
我真的更喜欢好的日志记录组件套件(CodeSite、SmartInspect),通常将其记录到各种文件中。例如,标准文件有“General”、“Debug”(我希望从客户端安装程序中收集的标准调试信息)、“Configuration”、“Services”和“Clients”。这些文件都被设置为“溢出”到一组编号文件中,只需允许更多的编号文件即可通过比较不同运行时的日志信息变得更加容易。
在你描述的情况下,我会添加记录到单独日志文件的调试语句。例如,“Trace”。使“Trace”可用的代码位于条件定义之间。这样,打开它变得非常简单。
为了避免留下这些额外的调试语句,我倾向于在没有从源代码控制检出的情况下进行更改以打开“Trace”日志。这样,构建服务器的编译器将在任何意外留下的语句上抛出“标识符未定义”的错误。如果我想保留这些额外语句,我会将它们更改为转到“Debug”日志或放置在条件定义之间。

感谢有关日志组件的提示。 我会查看一下。 但是,我发现对于一些高速实时关键调试情况,写入日志文件会干扰时间或甚至使其不可能。 但除了这个狭窄的用例之外,它们确实能帮助很多。 - Robert Oschler
1
@RobertOschler:我没有做过实时工作,但在我雇主的高性能、大量多线程服务器软件中,我们通常可以在记录大量日志之前得到足够的时间来改变行为并消除错误。当然,您需要保持日志消息简短,并尽可能避免字符串连接(使用格式化),内存重新分配,函数调用或属性获取器进行记录。 - Marjan Venema

2
我会先确保问题是你认为的那样。我很久没用Delphi了,所以不确定IDE的限制,但我有点怀疑事件日志会在20-30秒内写入相同数量的调试字符串时呈指数级增长。更有可能的是,由于某种原因,正在写入的调试字符串数量随着时间的推移而增加,这可能表明应用程序控制流中存在错误,如果禁用日志记录,则错误不太明显。
为了确保,我建议编写一个简单的应用程序,只需在循环中以100个为一组写出调试字符串,并开始记录每个组所需的时间,看看随着20-30秒时间段的推移,时间是否显著增加。
如果您验证了这个问题 - 或者即使不是 - 我建议使用某种类型的日志记录库。当您像这样使用OutputDebugString进行大规模日志转储时,它的效果真的会减弱。即使您找到了重置或限制输出窗口的方法,您也将失去所有日志数据。

谢谢。请看我在下面对Marjan的评论,关于日志记录的问题。 - Robert Oschler
1
一个好的日志库将允许您配置缓冲,这样您就不会因为每个日志条目都进行文件写入而受到影响,因此它不会比OutputDebugString更具破坏性。其中许多库还可以使用外部进程来处理日志条目,并通过共享内存传递日志条目,这本质上与OutputDebugString执行的操作相同。 - Gerald

1

IDE Fix Pack有一个优化,可以提高OutputDebugString的性能。

IDE的调试日志视图也得到了优化。现在,当IDE处于空闲状态时,调试器才会更新日志视图。这使得IDE在写入数百个OutputDebugString消息或其他调试消息到调试日志视图时仍能保持响应。

请注意,此功能仅适用于Delphi 2007及以上版本。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接