2010-04-06 8 views
5

Estoy usando MySql Connector .NET para cargar una cuenta y transferirla al cliente. Esta operación es bastante intensa, teniendo en cuenta los elementos secundarios de la cuenta para cargar.¿Hay alguna diferencia (de rendimiento) entre Depurar y Liberar?

En el modo de depuración, tarda como máximo 1 segundo para cargar la cuenta. El promedio sería 500ms. En el modo de lanzamiento, se tarda de 1 a 4 segundos en cargar la cuenta. El promedio sería 1500ms.

Dado que no existe una directiva #if DEBUG o similar en mi código, me pregunto de dónde viene la diferencia.

¿Existe una opción de compilación de proyecto que pueda cambiar? ¿O tiene que ver con MySql Connector .NET que tendría diferentes comportamientos dependiendo del modo de compilación?

EDIT: control de garrapatas.

Debug (Average: 213000 ticks) 
730000 
320000 
60000 
50000 
190000 
130000 
210000 
180000 
160000 
110000 
390000 
270000 
150000 
190000 
230000 
210000 
150000 
200000 
190000 
140000 

Release (Average: 4404500 ticks) 
12940000 
170000 
180000 
80000 
80000 
130000 
120000 
5060000 
5090000 
130000 
50000 
10430000 
25160000 
150000 
160000 
130000 
17620000 
10160000 
100000 
150000 

Comparación:

Release toma 20x el tiempo de depuración toma (comparación promedio).

4.404.500/213.000 = 20

Ahora, la primera operación es de hecho más tiempo, pero en general, por lo que son todas las otras veces para la liberación. ¿Alguna idea?

EDIT 2: Agregué incluso una prueba más amplia que calcula el tiempo total. Para cargas de 50 cuentas, toma un promedio de 4 segundos en depuraciones, y 40 segundos en lanzamiento. Estoy empezando a desesperarme por esto: es un problema serio de rendimiento para mi aplicación. ¿Alguien tiene una conjetura sobre cómo solucionar esto?

+0

¿Cómo está capturando el tiempo que lleva cargar una cuenta? ¿Estás realizando la operación varias veces dentro de un ciclo y tomando el promedio? ¿O está iniciando la aplicación como un nuevo proceso cada vez? –

+0

Existe una diferencia, excepto que generalmente es al revés, ya que la optimización del código no ocurre en el modo de depuración iirc. Sin embargo, puedo decir con certeza que el conector mysql .net nunca se ha comportado así en ningún proyecto en el que haya trabajado. –

+4

Utilice un generador de perfiles. Cualquier otra cosa es adivinar. –

Respuesta

1

Lo descubrí, permití código inseguro en una de las compilaciones de mis dependencias. Todavía me pregunto por qué se está comportando así, pero tendré que cavar esto un poco más.

¡Gracias por toda su ayuda!

8

Es posible que la diferencia en los tiempos se deba a un cambio en el momento en que se cargan los ensamblajes necesarios para su funcionamiento.

En el modo de lanzamiento, es posible que el tiempo de ejecución no necesite cargar inmediatamente un ensamblaje que su operación solo necesita más tarde (debido a varias optimizaciones realizadas para compilaciones de versiones). En consecuencia, en el modo de depuración un ensamblaje puede cargarse antes de que comience a cronometrar su operación, y en el modo de liberación ese ensamblaje puede cargarse después de que comience a cronometrar su operación. El tiempo para cargar el ensamblaje podría ser significativo dependiendo de qué tan grande sea el ensamblaje. Por supuesto, el ensamblaje debe cargarse en ambos casos, y solo tiene que cargarse una vez, por lo que las ejecuciones subsiguientes en el modo de lanzamiento pueden ser más rápidas.

Intente realizar su operación varias veces dentro de un bucle e ignorando la primera ejecución para encontrar el promedio menor de sobrecarga de inicio.

Actualización: Es interesante que los tiempos en el modo de disparo varían mucho en comparación con aquellos en el modo de depuración (el std dev es 100 veces más alta para el modo de disparo). En el extremo inferior, los tiempos del modo de liberación son comparables a los del modo de depuración. Menciona en su pregunta que cargar una cuenta es intensivo debido a todos los elementos secundarios que deben cargarse. Otra diferencia podría ser el punto en el que el tiempo de ejecución decide realizar la recolección de elementos no utilizados. Para probar, puede intentar realizar System.GC.Collect() después de cada operación (fuera de su temporizador) y ver si eso cambia las cosas.

Actualización: Si sospecha que puede haber un cambio en el comportamiento con respecto al bloqueo, es posible considerar el uso del Windows Monitor de rendimiento para supervisar los diversos contadores LocksAndThreads .NET CLR para el proceso de su aplicación (es) mientras ejecuta tus pruebas en los modos de depuración y liberación. Tal vez no está liberando correctamente un bloqueo en alguna parte y la ejecución se retrasa hasta que se agota el tiempo de espera. De ser así, esperaría ver un aumento en la tasa de contención reportada por los contadores de rendimiento. No estoy seguro de por qué esto solo sería un problema para las compilaciones de lanzamiento (a menos que realmente esté usando el depurador cuando ejecuta compilaciones de depuración).

+0

Hice lo que sugirió. Pregunta principal editada. – Lazlo

+0

Agregó el recolector de basura, no cambió los resultados. – Lazlo

+0

Podría probar su segunda solución cuando llegue a casa, pero aun así, no veo por qué solo afectaría la versión de lanzamiento. Probé todos los argumentos de línea de comando, y son exactamente, personaje por personaje, lo mismo. – Lazlo

2

Todo en las pestañas Construir y Depurar en la configuración de propiedades de la aplicación puede cambiar en función de la configuración de compilación. Algunos de estos se refieren solo a la etapa de compilación y no afectarán el rendimiento del tiempo de ejecución (Permitir código no seguro, Errores y advertencias, Tratar advertencias como errores y archivo de documentación XML). Los otros podrían hacer la diferencia.

Tomo nota de cada configuración que es diferente entre las configuraciones, luego cambio cada una de ellas para que las configuraciones coincidan, probando entre cada cambio. Entonces deberías ser capaz de encontrar el origen del problema.

Especialmente probar Definir DEPURACIÓN constante, Definir constante de TRACE, Símbolos de compilación condicionales, Objetivo de plataforma, Código de optimización, (en la pantalla Avanzado) Comprobar si hay desbordamiento/subdesbordamiento aritmético, Generar ensamblaje de serialización, Habilitar depuración de código no administrado y Habilitar el proceso de alojamiento de Visual Studio.

+0

He probado todas las que pude encontrar, aunque no pude encontrar lo siguiente: Plataforma de destino, Generar ensamblaje de serialización, Habilitar la depuración de código no administrado. Además, parece afectar cada operación de bloqueo ("hilo seguro"). Tendré que investigarlo más, pero la diferencia realmente es entre la depuración y la versión. En el modo de lanzamiento, obtengo resultados extremadamente extraños, incluso paquetes desconocidos (estoy creando un servidor). Creo que podría deberse a la diferencia de bloqueo en la depuración/liberación, pero incluso entonces, ¡no sé de dónde viene esto! Estoy empezando a estar desesperado por una solución. – Lazlo

Cuestiones relacionadas