Estamos obteniendo tiempos de compilación muy lentos, que pueden tomar más de 20 minutos en máquinas de doble núcleo de 2GHz y 2G Ram.
Mucho de esto se debe al tamaño de nuestra solución, que ha crecido a más de 70 proyectos, así como a VSS, que es un cuello de botella en sí mismo cuando tiene muchos archivos. (desafortunadamente, cambiar VSS no es una opción, así que no quiero que esto descienda a una fiesta VSS)
Estamos buscando proyectos de fusión. También estamos buscando tener múltiples soluciones para lograr una mayor separación de preocupaciones y tiempos de compilación más rápidos para cada elemento de la aplicación. Esto que puedo ver se convertirá en un infierno de DLL a medida que intentamos mantener las cosas sincronizadas.
Estoy interesado en saber cómo otros equipos han lidiado con este problema de escalado, qué haces cuando tu base de código alcanza una masa crítica que estás perdiendo la mitad del día viendo la barra de estado entregar mensajes de compilación.
ACTUALIZACIÓN Olvidé mencionar que esta es una solución de C #. Gracias por todas las sugerencias de C ++, pero han pasado algunos años desde que tuve que preocuparme por los encabezados.
EDITAR:
Buenas sugerencias que han ayudado hasta ahora (sin decir que no hay otras sugerencias agradables a continuación, solo lo que ha ayudado)
- Nueva computadora portátil de 3GHz: el poder de la utilización perdida hace maravillas cuando se maneja a la gerencia
- Deshabilitar antivirus durante la compilación
- 'Desconectarse' de VSS (en realidad la red) durante la compilación: puedo hacer que eliminemos la integración de VS-VSS por completo y que nos quedemos con el uso de la interfaz de usuario de VSS
Todavía no resoplando a través de una compilación, pero todo ayuda.
Orión mencionó en un comentario que los genéricos también pueden tener una obra de teatro. Según mis pruebas, parece haber un impacto mínimo en el rendimiento, pero no lo suficientemente alto como para garantizarlo: los tiempos de compilación pueden ser inconsistentes debido a la actividad del disco. Debido a limitaciones de tiempo, mis pruebas no incluyeron tantos Generics, o tanto código, como aparecería en el sistema en vivo, por lo que pueden acumularse. No evitaría usar genéricos donde se supone que deben usarse, solo para el rendimiento en tiempo de compilación
SOLUCIÓN ALTERNA
Estamos probando la práctica de construir nuevas áreas de la aplicación en nuevas soluciones, importando en los últimos dlls según sea necesario, integrándolos en la solución más grande cuando estamos contentos con ellos.
También podemos hacer lo mismo con el código existente mediante la creación de soluciones temporales que simplemente encapsulan las áreas en las que necesitamos trabajar y las desechamos después de reintegrar el código. Necesitamos sopesar el tiempo que llevará reintegrar este código contra el tiempo que ganamos al no tener Rip Van Winkle como experiencias de recompilación rápida durante el desarrollo.
fuente
Respuestas:
El equipo de Chromium.org enumeró varias opciones para acelerar la compilación (en este punto aproximadamente a la mitad de la página):
fuente
Tenemos casi 100 proyectos en una solución y un tiempo de desarrollo de desarrollo de solo segundos :)
Para el desarrollo local construye hemos creado un complemento de Visual Studio que los cambios
Project references
aDLL references
y descarga los proyectos no deseados (y una opción para cambiar de nuevo, por supuesto).Nuestras compilaciones ahora solo toman segundos cuando estamos trabajando en solo unos pocos proyectos a la vez. También podemos depurar los proyectos adicionales ya que se vincula a las DLL de depuración. La herramienta suele tardar entre 10 y 30 segundos en realizar una gran cantidad de cambios, pero no es necesario hacerlo con tanta frecuencia.
Actualización de mayo de 2015
El acuerdo que hice (en los comentarios a continuación) fue que lanzaría el complemento a Open Source si tiene suficiente interés. 4 años después tiene solo 44 votos (y Visual Studio ahora tiene dos versiones posteriores), por lo que actualmente es un proyecto de baja prioridad.
fuente
Tuve un problema similar en una solución con 21 proyectos y 1/2 millón de LOC. La mayor diferencia fue obtener discos duros más rápidos. Desde el monitor de rendimiento el 'Promedio. Disk Queue 'saltaría significativamente en la computadora portátil indicando que el disco duro era el cuello de botella.
Aquí hay algunos datos para los tiempos totales de reconstrucción ...
1) Laptop, Core 2 Duo 2GHz, 5400 RPM Drive (no estoy seguro de la memoria caché. Era Dell inspiron estándar).
Tiempo de reconstrucción = 112 segundos.
2) Escritorio (problema estándar), Core 2 Duo 2.3Ghz, solo 7200RPM Drive 8MB Cache.
Tiempo de reconstrucción = 72 segundos.
3) Desktop Core 2 Duo 3Ghz, solo 10000 RPM WD Raptor
Tiempo de reconstrucción = 39 segundos.
La unidad de 10,000 RPM no puede ser subestimada. Las compilaciones fueron significativamente más rápidas y todo lo demás, como mostrar documentación, el uso del explorador de archivos fue notablemente más rápido. Fue un gran aumento de la productividad al acelerar el ciclo de construcción de código.
Dado lo que las compañías gastan en los salarios de los desarrolladores, es una locura lo que pueden desperdiciar comprándolos con las mismas PC que usa la recepcionista.
fuente
Para compilaciones de C # .NET, puede usar .NET Demon . Es un producto que se hace cargo del proceso de compilación de Visual Studio para hacerlo más rápido.
Lo hace analizando los cambios que realizó y construye solo el proyecto que realmente cambió, así como otros proyectos que realmente se basaron en los cambios que realizó. Eso significa que si solo cambia el código interno, solo se necesita construir un proyecto.
fuente
Apaga tu antivirus. Agrega edades al tiempo de compilación.
fuente
Utiliza compilación distribuida. Xoreax IncrediBuild puede reducir el tiempo de compilación a unos pocos minutos.
Lo he usado en una gran solución C \ C ++ que generalmente tarda de 5 a 6 horas en compilarse. IncrediBuild ayudó a reducir este tiempo a 15 minutos.
fuente
Instrucciones para reducir el tiempo de compilación de Visual Studio a unos segundos
Desafortunadamente, Visual Studio no es lo suficientemente inteligente como para distinguir los cambios en la interfaz de un ensamblado de los cambios en el cuerpo del código sin importancia. Este hecho, cuando se combina con una gran solución entrelazada, a veces puede crear una tormenta perfecta de 'compilaciones completas' no deseadas casi cada vez que cambia una sola línea de código.
Una estrategia para superar esto es deshabilitar las compilaciones automáticas del árbol de referencia. Para hacer esto, use el 'Administrador de configuración' (Administrador de compilación / configuración ... luego en el menú desplegable Configuración de la solución activa, elija 'Nuevo') para crear una nueva configuración de compilación llamada 'ManualCompile' que copia de la configuración de depuración, pero no marque la casilla de verificación 'Crear nuevas configuraciones de proyecto'. En esta nueva configuración de compilación, desmarque cada proyecto para que ninguno de ellos se compile automáticamente. Guarde esta configuración presionando 'Cerrar'. Esta nueva configuración de compilación se agrega a su archivo de solución.
Puede cambiar de una configuración de compilación a otra a través del menú desplegable de configuración de compilación en la parte superior de su pantalla IDE (la que generalmente muestra 'Debug' o 'Release'). Efectivamente, esta nueva configuración de compilación ManualCompile hará inútiles las opciones del menú Generar para: 'Generar solución' o 'Reconstruir solución'. Por lo tanto, cuando está en el modo ManualCompile, debe compilar manualmente cada proyecto que está modificando, lo que se puede hacer haciendo clic con el botón derecho en cada proyecto afectado en el Explorador de soluciones y luego seleccionando 'Construir' o 'Reconstruir'. Debería ver que sus tiempos generales de compilación ahora serán solo segundos.
Para que esta estrategia funcione, es necesario que el Número de versión que se encuentra en los archivos AssemblyInfo y GlobalAssemblyInfo permanezca estático en la máquina del desarrollador (no durante las versiones de lanzamiento, por supuesto), y que no firme sus DLL.
Un riesgo potencial de usar esta estrategia de ManualCompile es que el desarrollador puede olvidarse de compilar los proyectos requeridos y, cuando inician el depurador, obtienen resultados inesperados (no pueden adjuntar el depurador, archivos no encontrados, etc.). Para evitar esto, probablemente sea mejor usar la configuración de compilación 'Debug' para compilar un esfuerzo de codificación más grande, y solo usar la configuración de compilación ManualCompile durante las pruebas unitarias o para realizar cambios rápidos de alcance limitado.
fuente
Si esto es C o C ++, y no está usando encabezados precompilados, debería estarlo.
fuente
Tuvimos más de 80 proyectos en nuestra solución principal, que tardó entre 4 y 6 minutos en construirse dependiendo del tipo de máquina que trabajara un desarrollador. Consideramos que es demasiado tiempo: por cada prueba realmente se come sus ETC.
Entonces, ¿cómo obtener tiempos de construcción más rápidos? Como parece que ya sabe, es la cantidad de proyectos los que realmente perjudican el tiempo de construcción. Por supuesto, no queríamos deshacernos de todos nuestros proyectos y simplemente lanzar todos los archivos fuente en uno. Sin embargo, teníamos algunos proyectos que podíamos combinar: sin embargo, como cada "proyecto de repositorio" en la solución tenía su propio proyecto unittest, simplemente combinamos todos los proyectos unittest en un proyecto global unittest. Eso redujo el número de proyectos con aproximadamente 12 proyectos y de alguna manera ahorró el 40% del tiempo para construir la solución completa.
Sin embargo, estamos pensando en otra solución.
¿También ha intentado configurar una nueva (segunda) solución con un nuevo proyecto? Esta segunda solución simplemente debe incorporar todos los archivos usando carpetas de soluciones. Porque es posible que se sorprenda al ver el tiempo de construcción de esa nueva solución con solo un proyecto.
Sin embargo, trabajar con dos soluciones diferentes tendrá una consideración cuidadosa. Los desarrolladores pueden estar inclinados a trabajar realmente en la segunda solución y descuidar completamente la primera. Como la primera solución con los más de 70 proyectos será la solución que se ocupa de su jerarquía de objetos, esta debería ser la solución donde su servidor de compilación debería ejecutar todas sus pruebas unitarias. Por lo tanto, el servidor para la integración continua debe ser el primer proyecto / solución. Tienes que mantener tu jerarquía de objetos, correcto.
La segunda solución con un solo proyecto (que se construirá mucho más rápido) será el proyecto donde todos los desarrolladores realizarán las pruebas y la depuración. ¡Sin embargo, debes cuidarlos mirando el servidor de compilación! Si algo se rompe DEBE ser reparado.
fuente
Asegúrese de que sus referencias sean referencias de Proyecto y no directamente a las DLL en los directorios de salida de la biblioteca.
Además, configure estos para que no se copien localmente, excepto cuando sea absolutamente necesario (el proyecto EXE maestro).
fuente
Publiqué esta respuesta originalmente aquí: /programming/8440/visual-studio-optimizations#8473 Puede encontrar muchas otras sugerencias útiles en esa página.
Si está utilizando Visual Studio 2008, puede compilar usando el indicador / MP para construir un solo proyecto en paralelo. He leído que esta también es una característica no documentada en Visual Studio 2005, pero nunca lo he probado.
Puede crear varios proyectos en paralelo utilizando el indicador / M, pero esto generalmente ya está configurado para la cantidad de núcleos disponibles en la máquina, aunque esto solo se aplica a VC ++, creo.
fuente
Noté que esta pregunta es antigua, pero el tema sigue siendo interesante hoy. El mismo problema me mordió últimamente, y las dos cosas que más mejoraron el rendimiento de compilación fueron (1) usar un disco dedicado (y rápido) para compilar y (2) usar la misma carpeta de salida para todos los proyectos, y configurar CopyLocal en False en el proyecto referencias
Algunos recursos adicionales:
fuente
Algunas herramientas de análisis:
herramientas-> opciones-> configuración del proyecto VC ++ -> Build Timing = Yes le dirá el tiempo de compilación para cada vcproj.
Agregue el
/Bt
interruptor a la línea de comando del compilador para ver cuánto tomó cada archivo CPPUtilícelo
/showIncludes
para capturar las inclusiones anidadas (archivos de encabezado que incluyen otros archivos de encabezado) y vea qué archivos podrían ahorrar una gran cantidad de E / S mediante el uso de declaraciones directas.Esto lo ayudará a optimizar el rendimiento del compilador al eliminar las dependencias y los cerdos de rendimiento.
fuente
Antes de gastar dinero para invertir en discos duros más rápidos, intente construir su proyecto completamente en un disco RAM (suponiendo que tenga la RAM de sobra). Puede encontrar varios controladores de disco RAM gratuitos en la red. No encontrará ninguna unidad física, incluidas las SSD, que sean más rápidas que un disco RAM.
En mi caso, un proyecto que tardó 5 minutos en construirse en un i7 de 6 núcleos en una unidad SATA de 7200 RPM con Incredibuild se redujo en solo unos 15 segundos mediante el uso de un disco RAM. Teniendo en cuenta la necesidad de volver a copiar en el almacenamiento permanente y la posibilidad de pérdida de trabajo, 15 segundos no es un incentivo suficiente para usar un disco RAM y probablemente no sea un gran incentivo para gastar varios cientos de dólares en una unidad SSD o RPM alta.
La pequeña ganancia puede indicar que la compilación estaba vinculada a la CPU o que el almacenamiento en caché de archivos de Windows fue bastante efectivo, pero dado que ambas pruebas se realizaron desde un estado en el que los archivos no se almacenaron en caché, me inclino mucho hacia las compilaciones vinculadas a la CPU.
Dependiendo del código real que esté compilando, su kilometraje puede variar, así que no dude en probar.
fuente
¿Qué tamaño tiene su directorio de compilación después de hacer una compilación completa? Si mantiene la configuración predeterminada, cada ensamblaje que construya copiará todas las DLL de sus dependencias y las dependencias de sus dependencias, etc. en su directorio bin. En mi trabajo anterior, cuando trabajaba con una solución de ~ 40 proyectos, mis colegas descubrieron que, con mucho, la parte más costosa del proceso de compilación era copiar estos ensamblajes una y otra vez, y que una compilación podría generar gigabytes de copias de las mismas DLL una y otra vez otra vez.
Aquí hay algunos consejos útiles de Patrick Smacchia, autor de NDepend, sobre lo que él cree que deberían y no deberían ser conjuntos separados:
http://codebetter.com/patricksmacchia/2008/12/08/advices-on-partitions-code-through-net-assemblies/
Básicamente, hay dos formas de evitar esto, y ambas tienen inconvenientes. Una es reducir el número de ensamblajes, lo que obviamente es mucho trabajo. Otra es reestructurar sus directorios de compilación para que todas sus carpetas bin estén consolidadas y los proyectos no copien las DLL de sus dependencias; no es necesario porque ya están todas en el mismo directorio. Esto reduce drásticamente la cantidad de archivos creados y copiados durante una compilación, pero puede ser difícil de configurar y puede dejarlo con algunas dificultades para extraer solo las DLL requeridas por un ejecutable específico para el empaquetado.
fuente
Quizás tome algunas funciones comunes y cree algunas bibliotecas, de esa manera las mismas fuentes no se compilan una y otra vez para múltiples proyectos.
Si le preocupa que se mezclen diferentes versiones de DLL, use bibliotecas estáticas.
fuente
Desactiva la integración de VSS. Es posible que no tenga la opción de usarlo, pero las DLL se renombran "accidentalmente" todo el tiempo ...
Y definitivamente verifique la configuración de encabezado precompilado. La guía de Bruce Dawson es un poco vieja, pero sigue siendo muy buena, échale un vistazo: http://www.cygnus-software.com/papers/precompiledheaders.html
fuente
Tengo un proyecto que tiene 120 o más exes, libs y dlls y toma un tiempo considerable para construirlo. Utilizo un árbol de archivos por lotes que llaman a crear archivos desde un archivo principal por lotes. He tenido problemas con cosas extrañas de encabezados incrementales (o fue temperamental) en el pasado, así que ahora los evito. Realizo una compilación completa con poca frecuencia, y generalmente la dejo al final del día mientras salgo a caminar durante una hora (por lo que solo puedo adivinar que me lleva aproximadamente media hora). Así que entiendo por qué eso no es viable para trabajar y probar.
Para trabajar y probar, tengo otro conjunto de archivos por lotes para cada aplicación (o módulo o biblioteca) que también tienen todas las configuraciones de depuración, pero aún así se llaman los mismos archivos de creación. Puedo activar y desactivar DEBUG de vez en cuando y también decidir sobre compilaciones o marcas o si también quiero compilar libs de las que el módulo puede depender, y así sucesivamente.
El archivo por lotes también copia el resultado completado en las (o varias) carpetas de prueba. Dependiendo de la configuración, esto se completa en varios segundos a un minuto (en lugar de decir media hora).
Usé un IDE diferente (Zeus) ya que me gusta tener control sobre cosas como archivos .rc, y en realidad prefiero compilar desde la línea de comandos, aunque estoy usando compiladores de MS.
Feliz de publicar un ejemplo de este archivo por lotes si alguien está interesado.
fuente
Deshabilite la indexación del sistema de archivos en sus directorios fuente (específicamente los directorios obj si desea que se pueda buscar su fuente)
fuente
Si se trata de una aplicación web, establecer la creación de lotes en verdadero puede ayudar dependiendo del escenario.
Puede encontrar una descripción general aquí: http://weblogs.asp.net/bradleyb/archive/2005/12/06/432441.aspx
fuente
También es posible que desee verificar las referencias circulares del proyecto. Fue un problema para mí una vez.
Es decir:
El proyecto A hace referencia al proyecto B
Proyecto B referencias Proyecto C
El proyecto C hace referencia al proyecto A
fuente
Una alternativa más económica a Xoreax IB es el uso de lo que yo llamo compilaciones de archivos uber. Básicamente es un archivo .cpp que tiene
Luego compila las unidades uber en lugar de los módulos individuales. Hemos visto tiempos de compilación desde 10-15 minutos hasta 1-2 minutos. Es posible que tenga que experimentar cuántos #incluye por archivo uber tiene sentido. Depende de los proyectos. etc. Quizás incluyas 10 archivos, quizás 20.
Usted paga un costo, así que tenga cuidado:
Es un poco doloroso, pero para un proyecto que es en gran medida estático en términos de nuevos módulos, el dolor inicial podría valer la pena. He visto este método vencer a IB en algunos casos.
fuente
Si se trata de un proyecto de C ++, entonces debería usar encabezados precompilados. Esto hace una gran diferencia en los tiempos de compilación. No estoy seguro de lo que realmente está haciendo cl.exe (sin usar encabezados precompilados), parece estar buscando muchos encabezados STL en todos los lugares incorrectos antes de finalmente ir a la ubicación correcta. Esto agrega segundos completos a cada archivo .cpp que se compila. No estoy seguro de si se trata de un error cl.exe, o algún tipo de problema STL en VS2008.
fuente
Mirando la máquina en la que está construyendo, ¿está configurada de manera óptima?
Acabamos de reducir nuestro tiempo de construcción para nuestro producto a escala empresarial C ++ más grande de 19 horas a 16 minutos al garantizar que se instaló el controlador de filtro SATA correcto.
Sutil.
fuente
Hay un modificador indocumentado / MP en Visual Studio 2005, consulte http://lahsiv.net/blog/?p=40 , que permitiría la compilación paralela en archivos en lugar de proyectos. Esto puede acelerar la compilación del último proyecto o, si compila un proyecto.
fuente
Al elegir una CPU: el tamaño de caché L1 parece tener un gran impacto en el tiempo de compilación. Además, generalmente es mejor tener 2 núcleos rápidos que 4 lentos. Visual Studio no usa los núcleos adicionales de manera muy efectiva. (Baso esto en mi experiencia con el compilador de C ++, pero probablemente también sea cierto para C # one).
fuente
Ahora también estoy convencido de que hay un problema con VS2008. Lo estoy ejecutando en una computadora portátil Intel de doble núcleo con 3G Ram, con el antivirus apagado. Compilar la solución a menudo es bastante hábil, pero si he estado depurando, una compilación posterior a menudo se ralentizará. A partir de la luz continua del disco principal, está claro que hay un cuello de botella de E / S de disco (también se puede escuchar). Si cancelo la compilación y el apagado VS, la actividad del disco se detiene. Reinicie VS, vuelva a cargar la solución y luego reconstruya, y es mucho más rápido. Unitl la próxima vez
Creo que este es un problema de paginación de memoria: VS simplemente se queda sin memoria y el O / S comienza a intercambiar páginas para intentar hacer espacio, pero VS exige más de lo que el intercambio de páginas puede ofrecer, por lo que se ralentiza a un rastreo. No puedo pensar en ninguna otra explicación.
VS definitivamente no es una herramienta RAD, ¿verdad?
fuente
¿Su empresa utiliza Entrust para su solución PKI / Encriptación por casualidad? Resulta que estábamos teniendo un rendimiento de compilación abismal para un sitio web bastante grande construido en C #, que duró más de 7 minutos en un Rebuild-All.
Mi máquina es una i7-3770 con 16 gb de ram y un SSD de 512 GB, por lo que el rendimiento no debería haber sido tan malo. Noté que mis tiempos de compilación eran increíblemente más rápidos en una máquina secundaria más antigua que construía la misma base de código. Así que encendí ProcMon en ambas máquinas, perfilé las compilaciones y comparé los resultados.
He aquí que la máquina de bajo rendimiento tenía una diferencia: una referencia al Entrust.dll en el stacktrace. Usando esta información recién adquirida, continué buscando StackOverflow y encontré esto: MSBUILD (VS2010) muy lento en algunas máquinas . Según la respuesta aceptada, el problema radica en el hecho de que el controlador Entrust estaba procesando las comprobaciones de certificados .NET en lugar del controlador nativo de Microsoft. También se sugiere que Entrust v10 resuelva este problema que prevalece en Entrust 9.
Actualmente lo tengo desinstalado y mis tiempos de compilación cayeron en picado a 24 segundos . YYMV con la cantidad de proyectos que está construyendo actualmente y es posible que no aborde directamente el problema de escala sobre el que estaba preguntando. Publicaré una edición de esta respuesta si puedo proporcionar una solución sin recurrir a una desinstalación del software.
fuente
Es seguro que hay un problema con VS2008. Porque lo único que he hecho es instalar VS2008 para actualizar mi proyecto que se ha creado con VS2005. Solo tengo 2 proyectos en mi solución. No es grande Compilación con VS2005: 30 segundos Compilación con VS2008: 5 minutos
fuente
Buenas sugerencias que han ayudado hasta ahora (sin decir que no hay otras sugerencias agradables a continuación, si tiene problemas, le recomiendo leer, entonces, lo que nos ha ayudado)
Todavía no resoplando a través de una compilación, pero todo ayuda.
También estamos probando la práctica de construir nuevas áreas de la aplicación en nuevas soluciones, importando en los últimos dlls según sea necesario, integrándolos en la solución más grande cuando estamos contentos con ellos.
También podemos hacer lo mismo con el código existente mediante la creación de soluciones temporales que simplemente encapsulan las áreas en las que necesitamos trabajar y las desechamos después de reintegrar el código. Necesitamos sopesar el tiempo que llevará reintegrar este código contra el tiempo que ganamos al no tener Rip Van Winkle como experiencias de recompilación rápida durante el desarrollo.
Orión mencionó en un comentario que los genéricos también pueden tener una obra de teatro. Según mis pruebas, parece haber un impacto mínimo en el rendimiento, pero no lo suficientemente alto como para garantizarlo: los tiempos de compilación pueden ser inconsistentes debido a la actividad del disco. Debido a limitaciones de tiempo, mis pruebas no incluyeron tantos Generics, o tanto código, como aparecería en el sistema en vivo, por lo que pueden acumularse. No evitaría usar genéricos donde se supone que deben usarse, solo para el rendimiento en tiempo de compilación
fuente