¿Hay una sobrecarga significativa asociada con la invocación de OutputDebugString en la versión de compilación?Sobrecarga asociada con OutputDebugString en la versión de lanzamiento
Respuesta
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
¿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;
}
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.
+1 por _es útil para poder activarlo en el campo_ –
que había leído en un artículo que OutputDebugString internamente hace algunas cosas interesantes:
- Crea \ Abre mutex y esperar infinitamente hasta mutex se adquiere.
- 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.
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.
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.
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?
- 1. sobrecarga asociada con excepción vs Throwable en Java
- 2. ¿Qué sobrecarga está asociada con un método de extensión en tiempo de ejecución? (NET)
- 3. Eliminar la referencia de NUnit para la versión de lanzamiento
- 4. Abrir archivo con la aplicación asociada
- 5. ¿Cómo verificar la versión de JRE antes del lanzamiento?
- 6. ¿Cómo probar la versión de lanzamiento en el dispositivo con Xcode 4.2?
- 7. Depuración de llamadas OutputDebugString en Delphi
- 8. OS X equivalente a OutputDebugString()?
- 9. Solo ensambles de signo con nombre seguro durante la versión de lanzamiento
- 10. En Delphi, ¿es seguro el subproceso OutputDebugString?
- 11. Ninguna aplicación está asociada con la excepción de archivos especificado
- 12. ¿Cómo encontrar la cuenta de Gmail asociada con Android Market?
- 13. ¿La información de stacktrace está disponible en la versión de lanzamiento de .NET?
- 14. Versión de lanzamiento de Android y "Waiting for Debugger"
- 15. ¿Cómo cambiar la "fuente asociada" de Eclipse para la depuración?
- 16. github ninguna dirección asociada con el nombre
- 17. vim: extensión asociada con el lenguaje
- 18. Sobrecarga de la horquilla()
- 19. ¿Cómo puedo recibir OutputDebugString desde un servicio?
- 20. Depuración de una versión de lanzamiento de una DLL (con archivo PDB)
- 21. Android: no se puede instalar la versión de lanzamiento en el emulador; El no conseguir [INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION]
- 22. problemas con Console.SetOut en modo de lanzamiento?
- 23. ¿Cómo puedo obtener la identificación de usuario asociada con un inicio de sesión en Linux?
- 24. La versión LIB es enorme en comparación con la depuración
- 25. nunidad en la versión de lanzamiento: "Common Language Runtime detectó un programa no válido".
- 26. ¿Se puede ver la salida de OutputDebugString en la ventana de salida de Visual Studio?
- 27. Sobrecarga + Operador con plantillas
- 28. modo de lanzamiento mucho más grande que la versión modo de depuración
- 29. sobrecarga y sobrecarga de Java
- 30. java.util.Collection con la sobrecarga más baja?
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. –
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