2009-10-08 37 views
9

Estoy usando Visual Studio, y parece que deshacerse de las referencias no utilizadas y usar las declaraciones acelera mi tiempo de construcción en proyectos más grandes. ¿Hay otras maneras conocidas de acelerar el tiempo de construcción? ¿Qué pasa con otros lenguajes y entornos de construcción?¿Cuáles son las formas de mejorar el tiempo de compilación/compilación?

¿Qué es típicamente el cuello de botella durante la compilación/compilación? Disco, CPU, memoria?

¿Cuál es una lista de/son buenas referencias para compilaciones distribuidas?

+3

En realidad, esto no es independiente del idioma. Diferentes idiomas tienen diferentes requisitos para un compilador, lo que afecta significativamente el tiempo de compilación, –

+0

Cierto, pero mi pregunta es más sobre cómo mejorar el rendimiento en diferentes compiladores, entornos, idiomas, etc. Generalmente uso Visual Studio, pero a veces msbuild, perl , etc. – esac

Respuesta

6

La mayor mejora que hicimos para nuestro gran proyecto de C++ fue la distribución de nuestras construcciones. Hace un par de años, una compilación completa tomaría aproximadamente media hora, mientras que ahora son unos tres minutos, de los cuales un tercio es tiempo de enlace.

Estamos usando un sistema de compilación propietario, pero IncrediBuild funciona bien para mucha gente (no pudimos hacerlo funcionar de manera confiable).

+0

+1 builds distribuidas = $$ –

+0

Quiero hacer una pregunta ¿cuál es la diferencia entre 'compile' y' build' – PageYe

3

Reparar las advertencias del compilador debería ayudar bastante.

+0

Solo si usa la herramienta de línea de comandos "cl". Escribir stdout en un archivo no es lento, incluso en Windows. – Lothar

+0

Solo tengo curiosidad si esto se debe simplemente a que se escriben en un archivo de registro que causa la desaceleración, por lo que si tiene pocas advertencias o si no hay ningún cuello de botella, ¿realmente no importará? – esac

+2

cualquier enlace para respaldar esto? nuestro programa genera más de 5000 advertencias de compilación y he estado buscando una buena excusa para remediar eso durante bastante tiempo –

1

Visual Studio admite compilaciones paralelas, lo que puede ayudar, pero el verdadero cuello de botella es el disco IO.

En C, por ejemplo, si genera archivos LST, su compilación demorará años.

+0

¿Qué es un archivo LST? –

+0

Un archivo de listado. Es una salida de instrucciones de ensamblaje para el código fuente dado. Muchas veces también incluye el texto del código fuente en línea con el ensamblaje para que pueda ver qué instrucciones están asociadas con qué líneas de código fuente. – sylvanaar

+0

yay SSD ....... – xaxxon

0

No compilar con la depuración activada.

+1

Esta es una mala sugerencia. Las compilaciones de depuración a menudo son necesarias. De hecho, la mayoría de sus compilaciones probablemente terminen siendo compilaciones de depuración porque ese es el modo que probablemente utilizará a medida que se desarrolla. –

+1

No dije que no fuera útil compilar con w/debug activado. La pregunta sobre cómo mejorar el tiempo de compilación solo. –

2

Lea este libro. Es bastante bueno en el tema de la estructura física de su proyecto en diferentes archivos con reconstrucciones mínimas.

Desafortunadamente fue escrito antes de que las plantillas se volvieran tan importantes. Las plantillas son el asesino en tiempo real cuando se trata de la compilación de C++. Especialmente si comete un error y usa punteros inteligentes en todas partes. En este caso, solo puede actualizar constantemente a la última CPU y unidades SSD recientes. MSVC ya es el compilador de C++ existente más reciente si usa encabezados precompilados.

http://ecx.images-amazon.com/images/I/51HNJ7KBBAL._BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA240_SH20_OU01_.jpg http://ecx.images-amazon.com/images/I/51HNJ7KBBAL._BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA240_SH20_OU01_.jpg

+1

¿Qué tiene que ver el uso de punteros inteligentes? –

3
+0

Este no es siempre el caso. Tengo un proyecto en el trabajo que acabo de actualizar de 2.83 GHz de última generación a procesadores de 3.2 GHz, ambos de cuatro núcleos. Doblo la cantidad de memoria de 8GB a 16GB. Cambié de RAID0 7200RPM a RAID0 15K SAS, y todavía no veo una mejora en el tiempo de compilación. Parece que hay otros factores a tener en cuenta. – esac

+0

Esto solo ayudará un poco. La distribución (ver mi respuesta) le dará muchos más ciclos. Pasamos de 3GHz a alrededor de 900 GHz cuando se distribuía. :) Saludos, Sebastiaan –

+0

Supongo que la actualización de 1 núcleo a 8 núcleos mejoraría mucho el rendimiento - Tal vez la E/S del disco sería el cuello de botella en este caso. –

3

En mi trabajo anterior tuvimos grandes problemas con el tiempo de compilación y una de las estrategias que utilizamos fue llamado el patrón de sobres ver here.

Básicamente intenta minimizar la cantidad de código copiado en los encabezados por el pre-procesador al minimizar el tamaño del encabezado. Lo hizo moviendo todo lo que no era público a una clase privada de amigos, he aquí un ejemplo.

foo.h:

class FooPrivate; 
class Foo 
{ 
public: 
    Foo(); 
    virtual ~Foo(); 
    void bar(); 
private: 
    friend class FooPrivate; 
    FooPrivate *foo; 
}; 

foo.cpp:

Foo::Foo() 
{ 
    foo = new FooPrivate(); 
} 

class FooPrivate 
{ 
    int privData; 
    char *morePrivData; 
}; 

Cuanto más incluir archivos que usted hace esto con el más que se suma. Realmente ayuda a tu tiempo de compilación.

Hace las cosas difíciles de depurar en VC6 aunque como aprendí de la manera difícil. Hay una razón por la cual es un trabajo anterior.

+0

Si no está satisfecho con lo que esta solución le hizo a su ciclo de mantenimiento, ¿por qué lo sugiere? –

+0

Como advertencia. Lo sugiero para que la gente sepa que existe y lo evite a toda costa. Funciona, reduce el tiempo de compilación, pero como dije, la depuración es casi imposible en VC6. – ReaperUnreal

2

Si está utilizando una gran cantidad de archivos y un gran número de código de plantillas (STL/BOOST/etc.), las compilaciones de Bulk o Unity deberían reducir los tiempos de compilación y enlace.

La idea de Bulk Builds es dividir su proyecto en subsecciones e incluir todos los archivos CPP en esa subsección en un único archivo. Las construcciones Unity llevan esto más lejos al tener un archivo CPP único que se compila y que incluye todos los demás archivos CPP.

La razón de esto es a menudo más rápido es:

1) plantillas sólo evalúan una vez al granel Archivo

2) Incluir archivos se abren/procesado sólo una vez por granel de archivos (suponiendo que hay una adecuada #ifndef FILE__FILENAME__H/#define FILE__FILENAME__H/#endif envoltorio en el archivo de inclusión). Reducir el total de E/S es una buena cosa para los tiempos de compilación.

3) El enlazador tiene mucha menos información para trabajar (archivo OBJ de Unidad Única o varios archivos Bulk OBJ) y es menos probable que entre en la memoria virtual.

EDITAR Adición de un couple de links aquí en desbordamiento de pila sobre la Unidad construye.

2

Tenga cuidado con el amplio barrido "considere este directorio y todos los subdirectorios para la inclusión del encabezado" en su proyecto. Esto hará que el compilador tenga que iterar cada directorio hasta que se encuentre el archivo de encabezado solicitado, y puede ser una operación muy costosa para tantos encabezados que incluya en su proyecto.

+0

Acepto que importa, pero, ¿es esto realmente "muy caro"? –

0

Para C++, el mayor cuello de botella es la E/S del disco. Muchos encabezados incluyen otros encabezados hacia adelante y hacia atrás, lo que hace que se abran y se lean muchos archivos para cada unidad de compilación.

Puede lograr una mejora significativa si mueve las fuentes a un disco RAM. Aún más si se asegura de que sus archivos de origen se lean exactamente una vez.

Así que para nuevos proyectos comencé a incluir todo en un solo archivo al que llamo _.cpp. Su estructura es así:

/* Standard headers */ 
#include <vector> 
#include <cstdio> 
//... 

/* My global macros*/ 
#define MY_ARRAY_SIZE(X) (sizeof(X)/sizeof(X[0])) 

// My headers 
#include "foo.h" 
#include "bar.h" 
//... 

// My modules 
#include "foo.cpp" 
#include "bar.cpp" 

Y solo compilo este único archivo.

Mis encabezados y archivos fuente no incluyen nada, y usan espacios de nombres para evitar conflictos con otros módulos.

Siempre que mi programa omita algo, agrego su encabezado y fuente en este módulo solamente.

De esta forma, cada archivo de origen y encabezado se lee exactamente una vez y se crea muy rápidamente. Los tiempos de compilación aumentan solo linealmente a medida que agrega más archivos, pero no en forma cuadrática. Mi proyecto de hobby es de aproximadamente 40000 loc y 500 módulos, pero todavía compila unos 10-20 segundos. Si muevo todas las fuentes y encabezados a un disco RAM, el tiempo de compilación se reduce a 3 segundos.

Desventaja de esto, que las bases de código existentes son bastante difíciles de refactorizar para usar este esquema.

0

Para C# - El uso de versiones fijas para sus ensambles en lugar de auto incrementales acelera en gran medida las compilaciones locales posteriores.

assemblyinfo.cs

// takes longer to update version number changes on all references to this assembly 
[assembly: AssemblyVersion("1.0.*")] 

// this way already built assemblies do not need to be recompiled 
// to update version number changes. 
[assembly: AssemblyVersion("1.0.0.0")] 
0

tiempo de compilación y el problema de la clase base frágil: he escrito un blog en una forma de mejorar el tiempo de compilación en C++. Link.

Cuestiones relacionadas