代码之家  ›  专栏  ›  技术社区  ›  Canopus

与版本构建中的OutputDebugString相关联的开销

  •  18
  • Canopus  · 技术社区  · 15 年前

    在版本构建中,是否存在与调用OutputDebugString相关的显著开销?

    7 回复  |  直到 9 年前
        1
  •  15
  •   sharptooth    15 年前

    测量-10米通话大约需要50秒。我认为这对于未使用的功能来说是一个很大的开销。

    使用宏有助于在发布版本中消除此问题:

    #ifdef _DEBUG
        #define LOGMESSAGE( str ) OutputDebugString( str );
    #else
        #define LOGMESSAGE( str )
    #endif
    

    不仅删除了调用,而且参数计算和文本字符串也被完全删除,在二进制文件中看不到它们。

        2
  •  11
  •   Eran    9 年前

    回答完这个问题后我写了这么长时间,但给出的答案遗漏了一个方面:

    当没有人在监听OutputDebugString的输出时,它可能非常快。但是,让一个监听器在后台运行(无论是dbgview、dbwin32、Visual Studio等)会使其速度慢10倍以上(在mt环境中慢得多)。原因是这些侦听器挂接报告事件,并且它们对事件的处理是在OutputDebugString调用的范围内完成的。此外,如果多个线程同时调用outputDebugString,它们将被同步。有关更多信息,请参阅 Watch out: DebugView (OutputDebugString) & Performance .

    作为附带说明,我认为除非您运行的是实时应用程序,否则您不应该担心运行1000万次呼叫需要50秒的设备。如果您的日志包含10米的条目,那么浪费的50秒是您的问题中最小的一个,现在您必须以某种方式分析这个野兽。一根10公里的原木听起来更合理,根据夏普图思的测量,只需要0.05秒。

    因此,如果您的输出在一个合理的大小内,那么使用outputDebugString不会对您造成太大的伤害。但是,请记住,一旦系统上的某个人开始监听此输出,就会出现速度减慢。

        3
  •  9
  •   aJ.    15 年前

    我在一篇文章中读到OutputDebugString在内部做了一些有趣的事情:

    1. 创建\打开互斥体并无限等待,直到获得互斥体。
    2. 在应用程序和调试器之间传递数据是通过一个4Kbyte的共享内存块完成的,有一个互斥体和两个事件对象保护对它的访问。

    即使没有附加调试程序(在发布模式下),在使用不同内核对象时使用outputDebugString也会带来巨大的成本。

    如果编写一个示例代码和测试,性能会受到很大影响。

        4
  •  8
  •   Bob Moore    14 年前

    这些年来,我在几十个服务器端发布模式的应用程序中没有发现任何问题,所有这些应用程序都有内置的度量标准。你可以得到 印象 这很慢,因为您可以找到的大多数调试捕捉器应用程序(dbwin32等)在将数据向上扔到屏幕上的速度非常慢,这给人留下了延迟的印象。

    当然,我们所有的应用程序默认都禁用了这个输出,但是 对于能够在字段中打开它很有用,因为您随后可以查看来自多个应用程序的调试输出,这些应用程序以类似dbwin32的方式序列化。对于涉及通信应用程序的错误,这是一种非常有用的调试技术。

        5
  •  6
  •   Stefan    15 年前

    不要将outputDebugString()调用保留在发布版本中。始终使用ifdef语句删除它们,或者提供另一个开关关闭它们。

    如果您将它们保留在中,则在默认情况下禁用它们,并且只在请求时激活它们,因为否则您的应用程序将很难调试其他行为良好的应用程序(即,只在请求时输出调试数据)。

    特雷斯 DebugView 为了捕捉应用程序的输出,当然,如果不是每个应用程序都无缘无故地喋喋不休的话,那才是好的。

        6
  •  4
  •   anon    15 年前

    为什么不自己测量呢?编译以下代码,运行它并计时。然后移除对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;
        }
    
        7
  •  2
  •   Stephen Kellett    14 年前

    我对这个话题很好奇,所以做了一些研究。

    我已经发布了结果、源代码和项目文件,以便您可以为您的设置重复测试。包括在不监视OutputDebugString的情况下运行发布模式应用程序,然后使用Visual Studio 6、Visual Studio 2005和Visual Studio 2010监视OutputDebugString来查看每个版本的Visual Studio在性能上有哪些差异。

    有趣的结果是,Visual Studio 2010处理输出调试信息的速度比Visual Studio 6慢7倍。

    全文如下: Whats the cost of OutputDebugString?