2009-04-08 12 views

Respuesta

14

Medido: las llamadas de 10M demoran unos 50 segundos. Creo que es una sobrecarga significativa para la funcionalidad no utilizada.

Usando una macro puede ayudar a deshacerse de esto en release:

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

no sólo elimina las llamadas, sino también la evaluación de los parámetros y las cadenas de texto son totalmente eliminado y no se va a ver en ellas el archivo binario

4

¿Por qué no medirlo usted mismo? Compile el siguiente código, ejecútelo & vez. A continuación, elimine la llamada a OutputDebugString, recompile y vuelva a ejecutar. Debe tomar cerca de tres minutos de su tiempo.

#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; 
    } 
+4

Tenga en cuenta que acaba de ejecutar este código no es toda la historia. El rendimiento estará determinado en gran medida por lo que supervisa el resultado de depuración (depurador DebugView, Visual Studio, etc.), y podría diferir dependiendo de la versión de Windows que esté ejecutando, por lo que debe probar en diferentes circunstancias. Tomaría mucho más de tres minutos de su tiempo. –

+1

He probado el fragmento de código anterior utilizando el tiempo de un hombre pobre (NULL) - inicio. Las 1000,000 veces demoran 13 segundos si activa OutputDebugString, pero no hay un depurador conectado, si abre DbgViewer para capturar la salida, el tiempo es 169 segundos. Si apaga OutputDebugString, el tiempo medido es 0 segundos. – zhaorufei

8

no he visto un problema en docenas de aplicaciones del lado del servidor de modo de liberación en los últimos años, todos los cuales se han incorporado en las métricas. Puede obtener la impresión que es lenta porque la mayoría de las aplicaciones de depurador que puede encontrar (DBWIN32 y otros) son bastante lentas al arrojar los datos a la pantalla, lo que da la impresión de retraso.

Por supuesto, todas nuestras aplicaciones tienen esta salida desactivada por defecto, pero es útil poder para encenderlo en el campo, ya que a continuación, puede ver la salida de depuración de varias aplicaciones, serializado en algo así como DBWin32 . Esta puede ser una técnica de depuración muy útil para errores que implican la comunicación de aplicaciones.

+0

+1 por _es útil para poder activarlo en el campo_ –

9

que había leído en un artículo que OutputDebugString internamente hace algunas cosas interesantes:

  1. Crea \ Abre mutex y esperar infinitamente hasta mutex se adquiere.
  2. Pasa los datos entre la aplicación y el depurador se realiza a través de un trozo de 4kbyte de memoria compartida, con un objeto Mutex y dos objetos de evento que protegen el acceso al mismo.

Incluso si el depurador no está conectado (en modo de lanzamiento) hay un costo significativo involucrado en el uso de OutputDebugstring con el uso de varios objetos kernel.

El golpe de rendimiento es muy evidente si escribe un código de muestra y una prueba.

6

Nunca deje las llamadas a OutputDebugString() en una compilación de versión. Siempre elimínelos utilizando instrucciones #ifdef, o proporcione otro interruptor para que se apaguen.

Si los deja, inhabilítenlos de manera predeterminada y solo actívelos cuando lo soliciten, porque de lo contrario, su aplicación dificultará la depuración de otras aplicaciones que se comporten bien (es decir, solo imprima datos de depuración si se solicitan).

Theres DebugView para captar el rendimiento de las aplicaciones, pero por supuesto que solo es bueno si no todas las aplicaciones charlan sin una buena razón.

10

estoy escribiendo esto mucho después de que esta pregunta ha sido contestada, pero las respuestas dadas perder un cierto aspecto:

OutputDebugString puede ser bastante rápido cuando nadie está escuchando a su salida.Sin embargo, tener un oyente ejecutándose en segundo plano (ya sea DbgView, DBWin32, Visual Studio, etc.) puede hacerlo más de 10 veces más lento (mucho más en el entorno MT). La razón es que esos oyentes conectan el evento de informe, y su manejo del evento se realiza dentro del alcance de la llamada OutputDebugString. Además, si varios subprocesos llaman a OutputDebugString al mismo tiempo, se sincronizarán. Para más información, vea Watch out: DebugView (OutputDebugString) & Performance.

Como nota al margen, creo que a menos que esté ejecutando una aplicación en tiempo real, no debería estar tan preocupado por una instalación que demora 50 segundos para ejecutar llamadas de 10M. Si su registro contiene 10 millones de entradas, los 50 segundos desperdiciados son el menor de sus problemas, ahora que tiene que analizar de alguna manera a la bestia. Un registro de 10K suena mucho más razonable, y crear eso tomará solo 0.05 segundos según la medida de Sharptooth.

Por lo tanto, si su salida está dentro de un tamaño razonable, usar OutputDebugString no debería hacerle mucho daño. Sin embargo, tenga en cuenta que se producirá una desaceleración cuando alguien en el sistema empiece a escuchar esta salida.

2

Tenía curiosidad sobre este tema, así que investigué.

He publicado los resultados, el código fuente y los archivos del proyecto para que pueda repetir las pruebas para su configuración. Cubre la ejecución de una aplicación de modo de lanzamiento sin que nada supervise OutputDebugString y luego con Visual Studio 6, Visual Studio 2005 y Visual Studio 2010 monitoreando OutputDebugString para ver qué diferencias en el rendimiento hay para cada versión de Visual Studio.

resultados interesantes, 2010 OutputDebugString procesos de información hasta 7 veces más lento que Visual Studio 6.

artículo completo aquí Visual Studio: Whats the cost of OutputDebugString?

Cuestiones relacionadas