Can*_*pus 18 windows performance winapi logging
在发布版本中调用OutputDebugString会产生很大的开销吗?
sha*_*oth 15
测量--10M通话大约需要50秒.我认为这对未使用的功能来说是一个巨大的开销.
使用宏可以帮助在发布版本中摆脱这个:
#ifdef _DEBUG
#define LOGMESSAGE( str ) OutputDebugString( str );
#else
#define LOGMESSAGE( str )
#endif
Run Code Online (Sandbox Code Playgroud)
不仅删除了调用,而且还完全删除了参数评估和文本字符串,您将不会在二进制文件中看到它们.
era*_*ran 12
在这个问题得到解答之后,我写这篇文章很久了,但给定的答案错过了某个方面:
当没有人正在监听其输出时,OutputDebugString可以非常快.然而,其在后台运行的监听器(无论是DBGVIEW,DBWin32时,Visual Studio等)可以使其超过10倍慢(在MT环境更多).原因是这些侦听器挂钩了报表事件,并且它们对事件的处理是在OutputDebugString调用的范围内完成的.此外,如果多个线程同时调用OutputDebugString,它们将被同步.有关更多信息,请参阅注意:DebugView(OutputDebugString)和性能.
作为旁注,我认为除非您正在运行实时应用程序,否则您不应该担心需要50秒才能运行10M呼叫的设施.如果您的日志包含10M条目,那么浪费的50秒是您遇到的问题中最少的,现在您必须以某种方式分析该野兽.一个10K的日志听起来更合理,根据sharptooth的测量创建只需0.05秒.
因此,如果您的输出在合理的大小范围内,使用OutputDebugString不会对您造成太大伤害.但是,请记住,一旦系统上有人开始收听此输出,就会发生减速.
我在一篇文章中读到OutPutDebugString内部做了一些有趣的事情:
即使没有附加调试器(在发布模式下),使用OutputDebugstring和使用各种内核对象也会产生很大的成本.
如果您编写示例代码并进行测试,性能影响非常明显.
多年来,我没有在数十个服务器端发布模式应用程序中看到任何问题,所有这些应用程序都具有内置指标.你可以得到它很慢的印象,因为你可以找到的大多数调试捕获器应用程序(DBWIN32等)在将数据投放到屏幕上的速度非常慢,这给人一种滞后的印象.
当然,我们的所有应用程序默认都禁用此输出,但是能够在该字段中打开它是很有用的,因为您可以查看来自多个应用程序的调试输出,这些应用程序在DBWin32之类的序列化中.对于涉及通信应用程序的错误,这可能是一种非常有用的调试技术.
小智 5
为什么不自己测量呢?编译以下代码,运行它并计时。然后删除对 OutputDebugString 的调用,重新编译并重新运行。应该花大约三分钟的时间。
#include <windows.h>
int main() {
const int COUNT = 1000000;
int z = 0;
for ( unsigned int i = 0; i < COUNT; i++ ) {
z += i;
OutputDebugString( "foo" );
}
return z;
}
Run Code Online (Sandbox Code Playgroud)
现有的答案可以追溯到 2009 / 2010 年。
\n虽然被遗忘的 OutputDebugString() 的性能可能没有太大变化,但我可以看出该工具产生了巨大的差异。
\n结论:
\n原来的 DebugView 太慢了,我减少了样本数量,以便在某个时候真正完成。
\nDebugView++ 做得非常出色。
\nVS 2019 似乎比旧版 Visual Studio 做得更好,在这个答案中提到。我无法比较自己,但它与 DebugView++ 非常接近,我认为它非常好。
\n测量结果:在单个 for 循环中调用 OutPutDebugStringW 100.000 次。所有构建都在发布模式下进行。Intel i7-6820HQ,2.7 GHz,限制为 99% 以防止睿频加速。使用std::chrono::high_resolution_clock::now()
100.000 次调用之前和之后的测量。
归档时间: |
|
查看次数: |
7715 次 |
最近记录: |