compiler - Optimizar el tiempo de compilación de plantillas en c++/gcc
gnu c c++ (2)
Encabezado precompilado
Si los cambios en el código no están en el encabezado, esto podría ayudar a reducir el tiempo de compilación. (src)
En un proyecto grande tenemos muchas clases (miles), y para cada una de ellas se define un tipo especial de puntero inteligente utilizando typedef. Este tipo de puntero inteligente es una clase de plantilla. Cuando compilo con "gcc -Q" veo que se pasa mucho tiempo compilando estos punteros inteligentes para cada clase. Es decir, veo los smartptr<class1>::methods, then smartptr<class2>::methods... smartptr<class2000>::methods
desplazándose en la pantalla mientras gcc los procesa.
¿Hay un truco para acelerar este proceso? Estas clases son todas iguales desde el punto de vista de smartptr, sin trucos enable_if, etc.
Lo que estoy tratando ahora mismo:
- tal vez hacer una clase base sin plantilla con algunos métodos comunes
- use la clase de plantilla externa para reducir los símbolos de enlace (y el tiempo de creación de instancias? no está seguro todavía)
Pero todo lo anterior no es una solución completa. Me pregunto si hay otra forma de optimizar el tiempo de compilación, un truco para que gcc sepa que, por ejemplo, si analizó smartptr una vez podría aplicar el mismo conocimiento una y otra vez al ver otras especializaciones, porque el código de generación es el mismo.
Sí, ya sé que no es exactamente lo mismo, por supuesto ... Pero es solo una idea loca.
O tal vez hay otros trucos que no conozco, que podrían acelerar la compilación. (Solo para dar una idea de lo que estoy hablando, podríamos optimizar otra plantilla eliminando su instanciación de datos de miembros estáticos, lo que redujo en gran medida el tiempo de compilación. Esto no era obvio en absoluto).
No específicamente GCC, pero creo que la idea de derivar smartptr
partir de una clase base sin plantilla parece una buena apuesta. Un puntero inteligente es un buen candidato para este enfoque porque a gran parte del código que se genera repetidamente no le importa que el puntero no sea void*
. (Cambiaría todo el código que pueda para que la plantilla de clase haga poco más que lanzar desde y hacia el void*
cuando sea necesario).
Además, si tiene miles de clases que dependen en gran medida de smartptr
, entonces debería considerar primero el problema de esta manera. Solo cuando eso falla, pasaría al código de cliente de smartptr
(en ese momento, vale la pena considerar las técnicas para evitar la hinchazón general del encabezado).
En cuanto a las declaraciones de plantillas externas , no tengo experiencia con estas, pero parece que necesitaría agregar una declaración extern
por typedef
. En particular, el efecto opuesto de forzar una instanciación completa se realiza de la siguiente manera:
template class smartptr<MyClass>;
Me gustaría comprobar que esta línea no acompaña a ninguna de sus typedef
s!