267 votes

Quelles techniques peuvent être utilisées pour accélérer les temps de compilation C ++?

Quelles techniques peuvent être utilisées pour accélérer la compilation C++?

Cette question s'est posée dans certains commentaires à Débordement de Pile question de la programmation en C++ de style, et je suis intéressé à entendre ce que les idées y sont.

J'ai vu une question connexe, Pourquoi ne la compilation C++ - il si long?, mais qui ne fournit pas beaucoup de solutions.


Voter ici ont Visual Studio prend en charge le partage des en-têtes précompilés entre les projets

263voto

Eclipse Points 27662

Les techniques de langage

Pimpl Idiome

Jetez un oeil à la Pimpl idiome ici, et ici, aussi connu comme un pointeur opaque ou gérer les classes. Non seulement d'accélérer la compilation, il augmente également l'exception de sécurité lorsqu'il est combiné avec un non-lancer swap fonction. Le Pimpl idiome vous permet de réduire les dépendances entre les en-têtes, et réduit la quantité de recompilation qui doit être fait.

Déclaration

Dans la mesure du possible, l'utilisation de l'avant déclarations. Si le compilateur a seulement besoin de savoir qu' SomeIdentifier est une structure ou un pointeur ou que ce soit, de ne pas inclure l'ensemble de définition, de forcer le compilateur à faire plus de travail que nécessaire. Cela peut avoir un effet de cascade, faisant de cette manière plus lente que dont ils ont besoin pour être.

Le I/O , les flux sont particulièrement connus pour ralentir les builds. Si vous en avez besoin dans un fichier d'en-tête, essayez de #y compris <iosfwd> au lieu de <iostream> et #inclure l' <iostream> d'en-tête dans le fichier d'implémentation. L' <iosfwd> - tête tient à l'avant garde des déclarations. Malheureusement, les autres en-têtes standard n'avez pas de déclarations d'en-tête.

Préfèrent passer par référence à passer-par-valeur en fonction de signatures. Cela permettra d'éliminer la nécessité de #inclure le type de définitions dans le fichier d'en-tête et vous aurez seulement besoin de déclarer le type. Bien sûr, préfèrent const références à la non-const références à éviter obscur de bugs, mais c'est une question par une autre question.

Les Conditions De La Garde

L'utilisation de la garde des conditions de garder les fichiers d'en-tête de plus d'une fois dans une seule unité de traduction.

#pragma once
#ifndef filename_h
#define filename_h

// Header declarations / definitions

#endif

En utilisant à la fois le réseau et les ifndef, vous bénéficiez de la portabilité de la plaine de macro solution, ainsi que la vitesse de compilation, l'optimisation de certains compilateurs peuvent le faire en présence de l' pragma once directive.

Réduire l'interdépendance

Le plus modulaire et moins interdépendants votre code de conception est, en général, moins souvent, vous aurez à tout recompiler. Vous pouvez également mettre fin à la réduction de la quantité de travail que le compilateur a à faire à une personne de bloc en même temps, en raison du fait qu'il a moins de garder une trace de.

Options du compilateur

Les En-Têtes Précompilés

Ceux-ci sont utilisés pour compiler une section commune des en-têtes une fois pour de nombreuses unités de traduction. Le compilateur compile une fois, et enregistre son état interne. Cet état peut ensuite être chargé rapidement pour obtenir une longueur d'avance dans la compilation d'un autre fichier avec le même ensemble d'en-têtes.

Assurez-vous d'inclure uniquement rarement changé des trucs dans les en-têtes précompilés, ou vous pourriez vous retrouver à faire le plein reconstruit plus souvent que nécessaire. C'est un bon endroit pour STL - têtes et d'autres de la bibliothèque de fichiers à inclure.

ccache est un autre utilitaire qui prend avantage des techniques de mise en cache pour accélérer les choses.

Utiliser Le Parallélisme

De nombreux compilateurs / IDEs en charge l'utilisation de plusieurs cœurs/Cpu pour faire de la compilation simultanément. Dans GNU Make (habituellement utilisé avec GCC), l'utilisation de l' -j [N] option. Dans Visual Studio, il y a une option dans les préférences pour lui permettre de construire de multiples projets en parallèle. Vous pouvez également utiliser l' /MP option de fichier de niveau paralellism, au lieu de simplement au niveau du projet paralellism.

Parallèlement d'autres utilitaires:

Un faible Niveau d'Optimisation

Le plus le compilateur essaie d'optimiser, plus il a de travailler.

Bibliothèques Partagées

Le déplacement de vos moins fréquemment code modifié dans les bibliothèques peuvent réduire le temps de compilation. En utilisant les bibliothèques partagées (.so ou .dll), vous pouvez réduire le temps de lien.

Obtenir un Ordinateur plus Rapide

Plus de RAM, plus rapide des disques durs (y compris les disques Ssd), de plus de Processeurs/cœurs feront une différence dans la vitesse de compilation.

33voto

Paulius Points 4148

Je recommande ces articles:

Certes, ils sont assez vieux, vous devrez re-tester tout ça avec les dernières versions (ou versions disponibles pour vous), pour obtenir des résultats réalistes. De toute façon, c'est une bonne source pour trouver des idées.

17voto

Frerich Raabe Points 23711

Une technique qui a travaillé très bien pour moi dans le passé: ne pas compiler plusieurs fichiers source C++ indépendamment, mais plutôt de générer un fichier C++, qui comprend tous les autres fichiers, comme ceci:

// myproject_all.cpp
// Automatically generated file - don't edit this by hand!
#include "main.cpp"
#include "mainwindow.cpp"
#include "filterdialog.cpp"
#include "database.cpp"

Bien sûr, cela signifie que vous devez recompiler tout le code source fourni dans le cas où les sources de changements, de sorte que l'arbre des dépendances est pas le pire. Cependant, la compilation de plusieurs fichiers source comme une unité de traduction est plus rapide (au moins dans mes expériences avec MSVC et GCC) et génère de plus petits fichiers binaires. Je pense aussi que le compilateur est donné plus de potentiel pour des optimisations (car il peut voir plus de code à la fois).

Cette technique pauses dans divers cas; par exemple, le compilateur s'en liberté sous caution dans le cas où deux ou plusieurs fichiers source déclarer une fonction globale avec le même nom. Je ne pouvais pas trouver cette technique décrite dans l'une des autres réponses, si, c'est pourquoi je le mentionne ici.

Pour ce que ça vaut, le Projet KDE utilisé cette même technique depuis 1999 pour construire optimisé binaires (peut-être pour une version). Le commutateur à l'accumulation de configurer le script a été appelé --enable-final. De l'intérêt archéologique j'ai creusé jusqu'à l'affichage qui a annoncé cette fonctionnalité: http://lists.kde.org/?l=kde-devel&m=92722836009368&w=2

16voto

Je vais juste le lien vers mon autre réponse: Comment réduire le temps de compilation, et le temps de lien pour les projets Visual C++? (c++ natif) . Un autre point que je veux ajouter, mais ce qui provoque souvent des problèmes est d'utiliser les en-têtes précompilés. Mais s'il vous plaît, ne les utiliser que pour les pièces qui ont à peine le changement (comme le GUI toolkit en-têtes). Sinon, ils vont vous coûter plus de temps qu'ils vous font gagner à la fin.

Une autre option, lorsque vous travaillez avec GNU make, pour allumer -j<N> option:

  -j [N], --jobs[=N]          Allow N jobs at once; infinite jobs with no arg.

J'ai l'habitude de l'avoir à l' 3 depuis que j'ai un dual core ici. Il va alors exécuter les compilateurs en parallèle pour les différentes unités de traduction, il n'existe pas de liens de dépendance entre eux. La liaison ne peut pas être fait en parallèle, car il y a un seul linker processus qui relie tous les fichiers objet. Mais l'éditeur de liens peut être fileté, et c'est ce que l' GNU gold ELF de l'éditeur de liens ne. Il est optimisé fileté code C++ qui est dit à link ELFE de fichiers objet d'une grandeur plus rapide que l'ancien ld (et a été effectivement inclus dans binutils).

15voto

ChrisW Points 37322

Il y a un livre entier sur ce sujet, intitulé " C ++ Software Design à grande échelle" (écrit par Lakos).

Le livre est antérieur à des modèles, donc au contenu de ce livre, ajouter "l'utilisation de modèles, aussi, peut rendre le compilateur plus lent".

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X