Debo admitir, que por lo general yo no he molestado el cambio entre el de Depuración y Liberación configuraciones en mi programa, y he optado por ir por la de Depuración de configuración, incluso cuando los programas se desplegó en el lugar de los clientes.

Hasta donde yo sé, la única diferencia entre estas configuraciones si no cambia de forma manual es que de Depuración tienen la DEBUG constante definida, y Liberación tienen la Optimizar el código marcado.

Así que mi pregunta es en realidad doble:

  1. Hay mucha diferencias de rendimiento entre estas dos configuraciones. ¿Hay algún tipo específico de código que va a causar grandes diferencias en el rendimiento de aquí, o es que realmente no es tan importante?

  2. ¿Hay algún tipo de código que se ejecuta bien en virtud de la de Depuración configuración que pueda fallar en Liberación de configuración, o puede usted estar seguro de que el código que está probado y funcionando muy bien en el de Depuración de configuración va a funcionar bajo la configuración de Lanzamiento.

InformationsquelleAutor | 2010-10-28

8 Comentarios

  1. 505

    El compilador de C# no alterar la emisión IL mucho en la versión de Lanzamiento. Notable es que ya no se emite el NOP códigos de operación que permiten establecer un punto de interrupción en una llave. El grande es el optimizador de que la integrada en el compilador JIT. Sé que hace las siguientes optimizaciones:

    • Método inline. Una llamada al método se sustituye por el de inyectar el código del método. Este es un grande, hace descriptores de acceso esencialmente libre.

    • Registro de CPU de asignación. Las variables locales y argumentos de método puede permanecer almacenado en un registro de CPU sin (o con menos frecuencia) se almacena de regreso al marco de pila. Este es un grande, notable para hacer la depuración de código optimizado tan difícil. Y dando la volátiles las palabras clave de un significado.

    • Índice de la matriz de comprobación de la eliminación. Una importante optimización cuando se trabaja con matrices (de todos .NET clases de colección de utilizar una matriz internamente). Cuando el compilador JIT, se puede comprobar que un bucle nunca los índices de un array fuera de los límites, a continuación, se eliminará el índice de verificación. Uno grande.

    • Bucle desenrollado. Bucles con cuerpos pequeños, mejoran de repetir el código de 4 veces en el cuerpo de un bucle de menos. Reduce la rama de costos y mejora el procesador de super-escalar las opciones de ejecución.

    • Eliminación de código muerto. Una declaración como if (false) { //} consigue completamente eliminado. Esto puede ocurrir debido a la constante plegable y alineaciones. Otro de los casos es donde el compilador JIT, se puede determinar que el código no tiene ningún efecto secundario posible. Esta optimización es lo que hace el código de generación de perfiles tan complicado.

    • Código de elevación. El código dentro de un bucle que no está afectada por el bucle se puede mover fuera del bucle. El optimizador de un compilador de C va a pasar mucho más tiempo en la búsqueda de oportunidades para la grúa. Sin embargo es una cara de optimización debido a la necesidad de flujo de datos y análisis de la fluctuación no puede permitirse el tiempo tan sólo polipastos casos obvios. Forzando .NET programadores a escribir mejor código fuente y de la grúa a sí mismos.

    • Común de la sub-expresión de la eliminación. x = y + 4; z = y + 4; se hace z = x; Bastante común en declaraciones como dest[ix+1] = src[ix+1]; escrito para mejorar la legibilidad, sin la introducción de una variable auxiliar. No hay necesidad de comprometer la legibilidad.

    • Constante de plegado. x = 1 + 2; se convierte en x = 3; Este simple ejemplo se detecta temprano por el compilador, pero que sucede en el JIT tiempo cuando otras optimizaciones que esto sea posible.

    • Copia de propagación. x = a; y = x; se convierte en y = a; Esto ayuda a que el registro de asignación de tomar mejores decisiones. Es una gran cosa en el x86 jitter porque tiene pocos registros para trabajar con. Tener que seleccionar los más adecuados es fundamental para perf.

    Estos son muy importantes optimizaciones que pueden hacer que un gran gran diferencia cuando, por ejemplo, el perfil de la compilación de Depuración de la aplicación y la comparamos con la versión de Lanzamiento. Que la única que realmente importa, sin embargo, cuando el código está en la ruta crítica, el 5 al 10% de el código de escritura que en realidad afecta a la perf de su programa. El JIT optimizador no es lo suficientemente inteligente como para saber lo que es fundamental, sólo puede aplicar la «vuelta a las once» marcado para todo el código.

    El resultado efectivo de estas optimizaciones en su ejecución del programa el tiempo es a menudo afectada por el código que se ejecuta en otros lugares. La lectura de un archivo, ejecutar una consulta de dbase, etc. Hacer el trabajo que el JIT optimizador hace completamente invisible. No cuenta, sin embargo 🙂

    El JIT optimizer es bastante fiable de código, sobre todo porque se ha puesto a la prueba de millones de veces. Es muy raro tener problemas en la versión de Lanzamiento de la versión de su programa. Sucede sin embargo. Tanto x64 y x86 nerviosismo ha tenido problemas con las estructuras. El x86 jitter tiene problemas con punto flotante de consistencia, produciendo sutilmente diferentes resultados cuando los productos intermedios de punto flotante, el cálculo se mantienen en un FPU registrarse en 80 bits de precisión en lugar de obtener truncado cuando tiraba a la memoria.

    • No creo que todo colecciones uso de la matriz(s): LinkedList<T> no, aunque no se utiliza muy a menudo.
    • Creo que el CLR configura la FPU 53 bits de precisión (coincidencia de 64 bits de ancho dobles), así que no hay de 80 bits extendido doble cálculos para Float64 valores. Sin embargo, Float32 cálculos pueden calcularse en esta 53 bits de precisión y sólo truncados cuando se almacenan en la memoria.
    • El volatile palabra clave no se aplica a las variables locales se almacenan en un marco de pila. A partir de la documentación en msdn.microsoft.com/en-us/library/x13ttww7.aspx: «La palabra clave volatile sólo puede ser aplicado a los campos de una clase o estructura. Las variables locales pueden ser declaradas volátil».
    • como un humilde enmienda, supongo que lo que realmente hace la diferencia entre Debug y Release construye en este sentido es la «optimizar el código» casilla de verificación que se encuentra normalmente en para Release, pero fuera de Debug. Es sólo para asegurarse de que los lectores no empezar a pensar que hay «magia», invisibles las diferencias entre las dos configuraciones de compilación que van más allá de lo que se encuentra en la página de propiedades del proyecto en Visual Studio.
    • Quizás vale la pena mencionar que prácticamente ninguno de los métodos en el Sistema.Los diagnósticos.Depuración de hacer cualquier cosa en una versión de depuración. También variables no terminadas bastante para ver rápidamente (stackoverflow.com/a/7165380/20553).
    • stackoverflow.com/a/17131389/17034
    • en realidad, de acuerdo a lo que Hans está diciendo, y cita a otros, lo que hace la gran diferencia para C# no la «optimizar el código» casilla de verificación, es si JIT se está ejecutando en Debug o Release modo. Que se determine si está conectado un depurador, no por que la casilla de verificación ni nada de lo hecho por el compilador de C#, ni siquiera si usted está construyendo en Debug o Release. Si entiendo correctamente, si se ha de adjuntar un depurador a un proceso de Liberación, perderá todas las optimizaciones de Hans menciona anteriormente.
    • Puede que nadie me señale algunos de los resultados de las pruebas que muestran la diferencia de rendimiento? En las pruebas que he hecho hasta ahora todavía tengo no se ve ninguna diferencia de rendimiento entre el funcionamiento de Depuración de las asambleas y la Liberación de las asambleas.

  2. 23
    1. Sí, hay muchas diferencias de rendimiento y estos realmente se aplican en todo el código. Depurar hace muy poco la optimización del rendimiento, y el modo de disparador mucho;

    2. Sólo el código que se basa en la DEBUG constante puede realizar de forma diferente con una versión de lanzamiento. Además de eso, usted no debería ver ningún problema.

    Un ejemplo de marco de trabajo de código que depende de la DEBUG constante es la Debug.Assert() método, que tiene el atributo de [Conditional("DEBUG)"] definido. Esto significa que también depende de la DEBUG constante y esto no está incluido en la versión de lanzamiento.

    • Todo esto es cierto, pero pudieron medir una diferencia? O notar una diferencia, mientras que el uso de un programa? Por supuesto no quiero animar a nadie a liberar su software en modo de depuración, pero la pregunta era si hay una gran diferencia de rendimiento y no veo que eso.
    • También es de destacar que las versiones de depuración se correlacionan con el código fuente original en un grado mucho mayor que la liberación de versiones. Si usted piensa (aunque poco probable) que alguien podría tratar de revertir la ingeniería de sus ejecutables, no desea que le sea más fácil mediante la implementación de las versiones de depuración.
    • Bueno, en estos días es difícil. Los procesadores han conseguido que rápido que el usuario apenas se espera un proceso en realidad se ejecuta el código, debido a una acción del usuario, así que esto es relativo. Sin embargo, si en realidad estás haciendo algún proceso largo, sí, usted se dará cuenta. El siguiente código, por ejemplo, se ejecuta un 40% más lenta en DEBUG: AppDomain.CurrentDomain.GetAssemblies().Sum(p => p.GetTypes().Sum(p1 => p1.GetProperties().Length)).
    • También, si usted está en asp.net y el uso de depuración en lugar de la liberación de algunas secuencias de comandos pueden ser añadidos en la página, tales como: MicrosoftAjax.debug.js que tiene unos 7k líneas.
  3. 12

    Esto depende en gran medida de la naturaleza de su aplicación. Si su aplicación es la interfaz de usuario pesado, probablemente no notará ninguna diferencia desde el componente más lento conectado a un ordenador moderno es el usuario. Si utiliza una interfaz de usuario animaciones, es posible que desee probar si se puede percibir notable retraso cuando se ejecuta en la versión de DEPURACIÓN.

    Sin embargo, si usted tiene muchos de cálculo pesados cálculos, entonces te darías cuenta de las diferencias (podría ser tan alto como el 40% como @Pieter de mencionar, aunque dependerá de la naturaleza de los cálculos).

    Es básicamente un diseño de equilibrio. Si usted está liberando en virtud de la generación de DEPURACIÓN, entonces, si las experiencias de los usuarios de los problemas, usted puede obtener más significativos sobre la procedencia del producto y que pueden hacer mucho más flexible de diagnóstico. Por la liberación en la generación de DEPURACIÓN, que también se evita el optimizador de la producción de ocultar Heisenbugs.

  4. 11
    • Mi experiencia ha sido que las medianas o grandes aplicaciones son notablemente más sensible en una versión de Lanzamiento. Pruébalo con tu aplicación y ver cómo se siente.

    • Una cosa que puede morder con las versiones de Lanzamiento es que la versión de Depuración de código a veces puede suprimir las condiciones de carrera y otros roscado relacionados con errores. Código optimizado puede resultar en la instrucción de reordenación y de ejecución más rápido puede exacerbar ciertas condiciones de carrera.

  5. 9

    Nunca se debe soltar una .RED de Depuración en la producción. Puede contener feo código para apoyar a Editar y Continuar o quién sabe qué otra cosa. Hasta donde yo sé, esto sucede sólo en VB no C# (nota: el post original está etiquetada C#), pero que todavía debe dar la razón para hacer una pausa en cuanto a lo que Microsoft piensa que se puede hacer con una versión de Depuración. De hecho, antes de la .NET 4.0, el código de VB fugas de memoria proporcional al número de instancias de objetos con eventos que se construye en apoyo de Editar y Continuar. (Aunque esto es informado de que se fija por https://connect.microsoft.com/VisualStudio/feedback/details/481671/vb-classes-with-events-are-not-garbage-collected-when-debugging, el código generado de aspecto desagradable, la creación de WeakReference los objetos y añadirlos a una lista estática mientras mantiene un bloqueo) yo ciertamente no quiero ninguna de este tipo de soporte de depuración en un entorno de producción!

    • Me he liberado de Depuración se basa muchas veces, y nunca he visto un problema. La única diferencia, quizás, es que nuestro servidor de aplicación no es una aplicación web de apoyo a una gran cantidad de usuarios. Pero es un servidor de aplicación con una muy alta carga de procesamiento. Desde mi experiencia, la diferencia entre Debug y Release parece completamente teórico. Yo nunca he visto ninguna diferencia práctica con alguna de nuestras aplicaciones.
  6. 5

    En mi experiencia, lo peor que ha salido de la Liberación modo oscura de la «liberación de errores». Desde la IL (intermediate language) es optimizado en modo de Lanzamiento, existe la posibilidad de errores que no se han manifestado en modo de Depuración. Hay otros PARA preguntas relativas a este problema:
    Las razones más comunes para bugs en la versión no está presente en el modo de depuración

    Esto me ha sucedido una o dos veces donde una sencilla aplicación de consola iba a ejecutar a la perfección en el modo de Depuración, pero dada la exacta misma entrada, sería error en el modo de Lanzamiento. Estos errores son MUY difíciles de depurar (por la definición de modo de Lanzamiento, irónicamente).

    • Para el seguimiento, he aquí un artículo que da un ejemplo de un Comunicado de Error: codeproject.com/KB/trace/ReleaseBug.aspx
    • Todavía es un problema si la aplicación ha sido probada y aprobada con la configuración de Depuración, incluso si se suprimen los errores, si que provoca la liberación de construir un error durante la implementación.
  7. 3

    Yo diría que 1) depende en gran medida de su aplicación. Generalmente, la diferencia no es enorme. Hice muchas de las mediciones y, a menudo, no podía ver una diferencia. Si utiliza el código no administrado, un montón de grandes matrices y cosas por el estilo, la diferencia de rendimiento es ligeramente más grande, pero no un mundo diferente (como en C++). 2) por lo general en el código de liberación menos errores se muestran (mayor tolerancia), por lo tanto, un interruptor debería funcionar bien.

    • Para el código que se IO obligado, una compilación de la versión que fácilmente podría ser no más que depurar.
  8. 0
        **Debug Mode:**
        Developer use debug mode for debugging the web application on live/local server. Debug mode allow developers to break the execution of program using interrupt 3 and step through the code. Debug mode has below features:
       1) Less optimized code
       2) Some additional instructions are added to enable the developer to set a breakpoint on every source code line.
       3) More memory is used by the source code at runtime.
       4) Scripts & images downloaded by webresource.axd are not cached.
       5) It has big size, and runs slower.
    
        **Release Mode:**
        Developer use release mode for final deployment of source code on live server. Release mode dlls contain optimized code and it is for customers. Release mode has below features:
        More optimized code
        Some additional instructions are removed and developer cant set a breakpoint on every source code line.
       1) Less memory is used by the source code at runtime.
       2) Scripts & images downloaded by webresource.axd are cached.
       3) It has small size, and runs fast.
       4) Scripts & images downloaded by webresource.axd are cached.
       5) It has small size, and runs fast.
    • parece que en el modo de disparador a veces, los primeros elementos de una lista no numerada correctamente. También algunos elementos dentro de la lista se duplican. 🙂

Dejar respuesta

Please enter your comment!
Please enter your name here