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

Quelles techniques peut-on utiliser pour accélérer les temps de compilation C++?

cette question a été soulevée dans certains commentaires à la question de débordement de pile C++ Style de programmation , et je suis intéressé d'entendre quelles idées il ya.

j'ai vu une question connexe, pourquoi la compilation C++ prend-elle autant de temps? , mais cela ne fournit pas beaucoup de solutions.


votez ici ont Visual Studio Support partage précompilé des en-têtes entre les projets

211
c++
demandé sur Community 2008-12-17 02:25:06

24 réponses

les techniques de Langage

Pimpl Idiom

regardez les pimpl idiom ici , et ici , aussi connu comme un pointeur opaque ou classes de poignée. Non seulement il accélère la compilation, mais il augmente également la sécurité d'exception lorsqu'il est combiné avec une fonction swap non lanceur . 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, utiliser forward declarations . Si le compilateur a seulement besoin de savoir que SomeIdentifier est une structure ou un pointeur, n'incluez pas la définition entière, forçant le compilateur à faire plus de travail qu'il n'en a besoin. Cela peut avoir un effet de cascade, en faisant ça plus lentement qu'ils n'ont besoin d'être.

les cours d'eau I/O sont particulièrement connus pour ralentir les constructions. Si vous en avez besoin dans un fichier d'en-tête, essayez #incluant <iosfwd> au lieu de <iostream> et #incluant l'en-tête <iostream> dans le fichier d'implémentation seulement. L'en-tête <iosfwd> ne contient que les déclarations forward. Malheureusement, les autres en-têtes standards n'ont pas d'en-tête de déclaration respective.

Préfèrent passer par référence à passer-par-valeur en fonction de signatures. Cela éliminera le besoin d'inclure les définitions de type respectives dans le fichier d'en-tête et vous n'aurez besoin que de transmettre-déclarer le type. Bien sûr, il est préférable de préférer les références const à des références non-const pour éviter les bugs obscurs, mais c'est un problème pour une autre question.

Conditions De Garde

utilisez les conditions de garde pour empêcher les fichiers d'en-tête d'être inclus plus de 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 pragma et l'ifndef, vous obtenez la portabilité de la solution macro simple, ainsi que l'optimisation de la vitesse de compilation que certains compilateurs peuvent faire en présence de la directive pragma once .

réduire l'interdépendance

plus votre conception de code est modulaire et moins interdépendante en général, moins vous aurez à recompiler tout. Vous pouvez également finir par réduire la quantité de travail que le compilateur doit faire sur n'importe quel bloc individuel en même temps, en vertu du fait qu'il a moins à suivre.

Options du compilateur

Headers Précompilés

ceux-ci sont utilisés pour compiler une section commune des en-têtes inclus une fois pour de nombreuses unités de traduction. Le compilateur le compile une fois, et sauve son état interne. Cet état peut alors ê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.

soyez prudent que vous incluez rarement des choses changées dans les en-têtes précompilés, ou vous pourriez finir par faire des reconstructions complètes plus souvent que nécessaire. C'est un bon endroit pour STL headers et d'autres bibliothèques comprennent des fichiers.

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

Utiliser Le Parallélisme

de nombreux compilateurs / IDEs prennent en charge l'utilisation de plusieurs noyaux/CPU pour effectuer la compilation simultanément. Dans GNU Make (généralement utilisé avec GCC), utilisez l'option -j [N] . Dans Visual Studio, il y a une option sous préférences pour lui permettre de construire plusieurs projets en parallèle. Vous pouvez également utiliser la /MP option pour le paralellisme au niveau du fichier, au lieu de juste au niveau du projet paralellism.

autres services publics parallèles:

utiliser un niveau D'optimisation plus faible

plus le compilateur essaie d'optimiser, plus il doit travailler.

Bibliothèques Partagées

déplacer votre code modifié moins fréquemment dans les bibliothèques peut réduire le temps de compilation. En utilisant des bibliothèques partagées ( .so ou .dll ), vous pouvez également réduire le temps de connexion.

Obtenir un Ordinateur plus Rapide

plus de RAM, des disques durs plus rapides (y compris les SSD), et plus de CPUs/Core feront une différence dans la vitesse de compilation.

228
répondu Eclipse 2015-05-31 06:45:00

je vous recommande ces articles de "Games from Within, Indie Game Design And Programming":

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

28
répondu Paulius 2015-03-22 00:41:57

je travaille sur le projet STAPL qui est une bibliothèque C++ fortement-templated. De temps en temps, nous devons revoir toutes les techniques pour réduire le temps de compilation. Ici, j'ai résumé les techniques que nous utilisons. Certaines de ces techniques sont déjà énumérées ci-dessus:

trouver les sections qui prennent le plus de temps

bien qu'il n'y ait pas de corrélation prouvée entre la longueur des symboles et le temps de compilation, nous avons observé que la moyenne plus faible les tailles de symboles peuvent améliorer le temps de compilation sur tous les compilateurs. Donc votre premier but il pour trouver les plus grands symboles dans votre code.

Méthode 1-symboles de tri basés sur la taille

vous pouvez utiliser la commande nm pour lister les symboles en fonction de leur taille:

nm --print-size --size-sort --radix=d YOUR_BINARY

dans cette commande le --radix=d vous permet de voir les tailles en nombres décimaux (par défaut est hex). Maintenant, en regardant le plus grand symbole, de déterminer si vous pouvez cassez la classe correspondante et essayez de la redessiner en factorisant les parties non-templated dans une classe de base, ou en divisant la classe en plusieurs classes.

Méthode 2-symboles de tri basés sur la longueur 1519510920"

vous pouvez exécuter la commande régulière nm et la pipe à votre script préféré ( AWK , Python , etc.) pour trier les symboles basés sur leur longueur . Basé sur notre expérience, cette méthode identifie la plus grande difficulté à rendre les candidats mieux que la méthode 1.

Méthode 3 - Use Templight

Templight est un Clang outil basé pour profiler le temps et la consommation de mémoire des instanciations de template et pour effectuer des sessions de débogage interactives pour gagner l'introspection dans le processus d'instanciation de template".

vous pouvez installer Templight en cochant LLVM et Clang ( instructions ) et en appliquant le patch Templight dessus. Le réglage par défaut pour LLVM et Clang est sur debug et assertions, et ceux-ci peuvent affecter votre temps de compilation de manière significative. Il semble que Templight ait besoin des deux, donc vous devez utiliser les paramètres par défaut. Le processus d'installation de LLVM et Clang devrait prendre environ une heure.

après avoir appliqué le patch, vous pouvez utiliser templight++ situé dans le dossier de compilation que vous avez spécifié lors de l'installation pour compiler votre code.

assurez-vous que templight++ est sur votre chemin. Maintenant, pour compiler, ajoutez les commutateurs suivants à votre CXXFLAGS dans votre Makefile ou à vos options en ligne de commande:

CXXFLAGS+=-Xtemplight -profiler -Xtemplight -memory -Xtemplight -ignore-system

ou

templight++ -Xtemplight -profiler -Xtemplight -memory -Xtemplight -ignore-system

après compilation est fait, vous aurez un .trace.mémoire.le pbf et .trace.pbf généré dans le même dossier. Visualiser ces traces, vous pouvez utiliser le Templight Tools qui peut les convertir à d'autres formats. Suivez ces instructions pour installer templight-convert. Nous utilisons habituellement la sortie callgrind. Vous pouvez également utiliser la sortie GraphViz si votre projet est petit:

$ templight-convert --format callgrind YOUR_BINARY --output YOUR_BINARY.trace

$ templight-convert --format graphviz YOUR_BINARY --output YOUR_BINARY.dot

le fichier callgrind généré peut être ouvert en utilisant kcachegrind dans lequel vous pouvez tracer le plus de temps / de mémoire consommant instanciation.

Réduire le nombre d'instanciations du modèle

bien qu'il n'existe pas de solution précise pour réduire le nombre d'instanciations de gabarits, il existe quelques lignes directrices qui peuvent aider:

Refactor classes avec plus d'un modèle arguments

Par exemple, si vous avez une classe,

template <typename T, typename U>
struct foo { };

et les deux de T et U peuvent avoir 10 options différentes, vous avez augmenté les instanciations de template possibles de cette classe à 100. Une façon de résoudre cela est d'abstraire la partie commune du code à une classe différente. L'autre méthode consiste à utiliser l'inversion héréditaire (inverser la hiérarchie de classe), mais assurez-vous que vos objectifs de conception ne sont pas compromis avant d'utiliser cette technique.

Refactor non-basé sur un modèle de code à personne d'unités de traduction

en utilisant cette technique, vous pouvez compiler la section commune une fois et la lier avec vos autres ut (unités de traduction) plus tard.

utiliser instanciations de template extern (depuis C++11)

si vous connaissez toutes les instanciations possibles d'une classe, vous pouvez utiliser cette technique pour compiler tous les cas dans une unité de traduction différente.

par exemple, dans:

enum class PossibleChoices = {Option1, Option2, Option3}

template <PossibleChoices pc>
struct foo { };

Nous savons que cette classe peut avoir trois instanciations:

template class foo<PossibleChoices::Option1>;
template class foo<PossibleChoices::Option2>;
template class foo<PossibleChoices::Option3>;

mettez ce qui précède dans une unité de traduction et utilisez le mot-clé externe dans votre fichier d'en-tête, au-dessous de la définition de la classe:

extern template class foo<PossibleChoices::Option1>;
extern template class foo<PossibleChoices::Option2>;
extern template class foo<PossibleChoices::Option3>;

cette technique peut vous faire gagner du temps si vous compilez différents tests avec un ensemble commun d'instanciations.

NOTE : MPICH2 ignore l'instanciation explicite à ce point et compile toujours les classes instanciées dans toutes les unités de compilation.

Use construction de l'unité

toute l'idée derrière l'unité construit doit inclure tous les .cc fichiers que vous utilisez dans un fichier et compiler ce fichier une seule fois. En utilisant cette méthode, vous pouvez éviter de réinstenter les sections communes de différents fichiers et si votre projet inclut beaucoup de fichiers communs, vous sauveriez probablement aussi sur les accès disque.

par exemple, supposons que vous avez trois fichiers foo1.cc , foo2.cc , foo3.cc et ils comprennent tous tuple de STL . Vous pouvez créer un foo-all.cc qui ressemble à:

#include "foo1.cc"
#include "foo2.cc"
#include "foo3.cc"

vous compilez ce fichier une seule fois et réduisez potentiellement les instanciations communes entre les trois fichiers. Il est difficile d'estimer si l'amélioration est significative ou non. Mais un fait évident, c'est que vous perdre parallélisme dans vos constructions (vous ne pouvez plus compiler les trois fichiers en même temps).

en Outre, si aucun de ces fichiers n'arrive à prendre beaucoup de mémoire, vous pouvez exécuter de mémoire avant que la compilation est terminée. Sur certains compilateurs ,comme GCC , cela pourrait geler (erreur de compilateur Interne) votre compilateur pour manque de mémoire. Alors n'utilisez pas cette technique à moins de connaître tous les avantages et les inconvénients.

headers précompilés

précompilé headers (PCHs) peut vous sauver beaucoup de temps dans la compilation en compilant vos fichiers d'en-tête à une représentation intermédiaire reconnaissable par un compilateur. Pour générer des fichiers d'en-tête précompilés, vous n'avez qu'à compiler votre fichier d'en-tête avec votre commande de compilation régulière. Par exemple, sur GCC:

$ g++ YOUR_HEADER.hpp

cela générera un YOUR_HEADER.hpp.gch file ( .gch est l'extension pour les fichiers PCH dans GCC) dans le même dossier. Cela signifie que si vous incluez YOUR_HEADER.hpp dans autre fichier, le compilateur utilisera votre YOUR_HEADER.hpp.gch au lieu de YOUR_HEADER.hpp dans le même dossier auparavant.

il y a deux problèmes avec cette technique:

  1. vous devez vous assurer que les fichiers d'en-tête précompilés sont stables et ne vont pas changer ( vous pouvez toujours changer votre makefile )
  2. vous ne pouvez inclure QU'un PCH par unité de compilation (sur la plupart des compilateurs). Ce signifie que si vous avez plus d'un fichier d'en-tête pour être précompilés, vous devez les inclure dans un fichier (par exemple, all-my-headers.hpp ). Mais que signifie que vous devez inclure le fichier dans tous les lieux. Heureusement, GCC a une solution à ce problème. Utiliser -include et donnez-lui le nouveau fichier d'en-tête. Vous pouvez comma séparer les différents fichiers en utilisant cette technique.

par exemple:

g++ foo.cc -include all-my-headers.hpp

utiliser des espaces de noms anonymes ou anonymes

Unnamed namespaces (A. K. A. anonymous namespaces) peut réduire les tailles binaires générés de manière significative. Les namespaces sans nom utilisent un lien interne, ce qui signifie que les symboles générés dans ces namespaces ne seront pas visibles par les autres TU (unités de traduction ou de compilation). Les compilateurs génèrent habituellement des noms uniques pour des espaces de noms sans nom. Cela signifie que si vous avez un fichier foo.hpp:

namespace {

template <typename T>
struct foo { };
} // Anonymous namespace
using A = foo<int>;

et il se trouve que inclure ce fichier en deux TUs (deux .cc et les compiler séparément). Les deux modèles de foo ne seront pas les mêmes. Cela viole la " One Definition Rule (ODR). Pour la même raison, utiliser des namespaces sans nom est déconseillé dans les fichiers d'en-tête. N'hésitez pas à utiliser dans votre .cc pour éviter les symboles montrant dans votre fichiers binaires. Dans certains cas, la modification de tous les détails internes pour un fichier .cc a montré une réduction de 10% de la taille du binaire.

changer les options de visibilité

dans les nouveaux compilateurs, vous pouvez sélectionner vos symboles pour être visibles ou invisibles dans les objets partagés dynamiques (DSOs). Idéalement, changer la visibilité peut améliorer les performances du compilateur, lier les optimisations de temps (LTOs) et générer des tailles binaires. Si vous regardez les fichiers d'en-tête STL dans GCC, vous pouvez voir qu'il est largement utilisé. Pour activer les choix de visibilité, vous devez changer votre code par fonction, par classe, par variable et surtout par le compilateur.

avec l'aide de la visibilité, vous pouvez cacher les symboles que vous considérez comme privés des objets partagés générés. Sur GCC, vous pouvez contrôler la visibilité des symboles en passant par défaut ou caché à l'option -visibility de votre compilateur. C'est dans un certain sens similaire à l'Espace-nom sans nom, mais d'une manière plus élaborée et intrusive.

si vous souhaitez spécifier le visibilités par cas, vous devez ajouter les attributs suivants à vos fonctions, variables, et classes:

__attribute__((visibility("default"))) void  foo1() { }
__attribute__((visibility("hidden")))  void  foo2() { }
__attribute__((visibility("hidden")))  class foo3   { };
void foo4() { }

la visibilité par défaut dans GCC est par défaut (publique), ce qui signifie que si vous compilez ce qui précède comme une méthode de bibliothèque partagée ( -shared ), foo2 et la classe foo3 ne seront pas visibles dans les autres TUs ( foo1 et foo4 seront visibles). Si vous compilez avec -visibility=hidden alors seulement foo1 sera visible. Même foo4 serait caché.

vous pouvez en savoir plus sur la visibilité sur GCC wiki .

26
répondu Mani Zandifar 2017-02-08 19:13:38

il y a un livre entier sur ce sujet, qui est intitulé conception de logiciel C++ à grande échelle (écrit par John Lakos).

le livre pré-dates gabarits, ainsi au contenu de ce livre ajouter "en utilisant des gabarits, aussi, peut rendre le compilateur plus lent".

15
répondu ChrisW 2015-05-31 08:06:12

je vais juste faire un lien vers mon autre réponse: comment réduisez-vous le temps de compilation, et le temps de liaison pour les projets C++ visuels (C++natif)? . Un autre point que je voudrais ajouter, mais qui provoque souvent des problèmes est d'utiliser des en-têtes précompilés. Mais s'il vous plaît, ne les utilisez que pour les pièces qui ne changent presque jamais (comme les en-têtes GUI toolkit). Sinon, ils vous coûteront plus de temps qu'ils ne vous sauveront à la fin.

une autre option est, lorsque vous travailler avec GNU make, pour activer l'option -j<N> :

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

Je l'ai d'habitude à 3 puisque j'ai un double noyau ici. Il exécutera alors des compilateurs en parallèle pour différentes unités de traduction, à condition qu'il n'y ait pas de dépendances entre elles. Le lien ne peut pas être fait en parallèle, puisqu'il n'y a qu'un seul processus de linker reliant tous les fichiers objet.

Mais le linker lui-même peut être fileté, et c'est ce que le GNU gold ELF de l'éditeur de liens ne. C'est du code C++ fileté optimisé qui est censé lier des fichiers d'objets ELF d'une magnitude plus rapide que l'ancien ld (et qui a été en fait inclus dans binutils ).

15
répondu Johannes Schaub - litb 2017-05-23 11:33:25

une technique qui a très bien fonctionné pour moi dans le passé: ne compilez pas plusieurs fichiers source C++ de manière indépendante, mais plutôt générer un fichier C++ qui inclut 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 inclus dans le cas où l'une des sources change, donc l'arbre de dépendances devient pire. Cependant, compiler plusieurs fichiers source en une seule unité de traduction est plus rapide (du moins dans mes expériences). avec MSVC et GCC) et génère des binaires plus petits. Je soupçonne également que le compilateur est donné plus de potentiel pour des optimisations (puisqu'il peut voir plus de code à la fois).

cette technique casse dans divers cas; par exemple, le compilateur va se renflouer dans le cas où deux ou plusieurs fichiers source déclarent une fonction globale avec le même nom. Je n'ai trouvé cette technique décrite dans aucune des autres réponses, c'est pourquoi je la mentionne ici.

pour ce que ça vaut, le KDE Project a utilisé cette même technique depuis 1999 pour construire des binaires optimisés (éventuellement pour une version). Le commutateur vers le script de configuration de construction a été appelé --enable-final . Par intérêt archéologique, j'ai déterré l'annonce qui annonçait ce trait: http://lists.kde.org/?l=kde-devel&m=92722836009368&w=2

14
répondu Frerich Raabe 2015-05-31 08:08:34

En voici quelques-uns:

  • utilisez tous les cœurs de processeur en démarrant un travail de compilation multiple ( make -j2 est un bon exemple).
  • désactiver ou réduire les optimisations (par exemple, GCC est beaucoup plus rapide avec -O1 que -O2 ou -O3 ).
  • utiliser headers précompilés .
11
répondu Milan Babuškov 2015-05-31 06:33:54

une fois que vous avez appliqué toutes les astuces de code ci-dessus (déclarations forward, réduction de l'inclusion d'en-tête au minimum dans les en-têtes publics, poussant la plupart des détails à l'intérieur du fichier d'implémentation avec Pimpl ...) et rien d'autre ne peut être acquise de langage, pensez à votre système de construction. Si vous utilisez Linux, envisagez d'utiliser distcc (compilateur distribué) et ccache (compilateur cache).

le premier, distcc, exécute l'étape du préprocesseur localement et envoie ensuite la sortie au premier compilateur disponible dans le réseau. Il nécessite les mêmes versions de compilateur et de bibliothèque dans tous les noeuds configurés du réseau.

ce dernier, ccache, est un cache de compilateur. Il exécute de nouveau le préprocesseur et vérifie ensuite avec une base de données interne (détenue dans un répertoire local) si ce fichier de préprocesseur a déjà été compilé avec les mêmes paramètres de compilateur. Si il le fait, c'est juste affiche le binaire et de sortie de la première manche du compilateur.

les deux peuvent être utilisés en même temps, de sorte que si ccache n'a pas de copie locale, il peut l'envoyer par le réseau à un autre noeud avec distcc, ou bien il peut simplement injecter la solution sans autre traitement.

10
répondu David Rodríguez - dribeas 2015-05-31 07:51:41

quand je suis sorti de l'université, le premier code C++ digne de la production que j'ai vu avait ces #ifndef ... # endif directives entre les deux où les en-têtes ont été définis. J'ai demandé au gars qui écrivait le code à propos de ces choses globales d'une manière très naïve et a été présenté au monde de la programmation À grande échelle.

pour en revenir au sujet, l'utilisation de directives pour empêcher les définitions d'en-tête dupliquées a été la première chose que j'ai apprise quand il s'est agi de réduction des temps de compilation.

9
répondu questzen 2015-05-31 06:37:05

plus de RAM.

Quelqu'un a parlé de RAM drives dans une autre réponse. Je l'ai fait avec un 80286 et Turbo C++ (montre l'âge) et les résultats ont été phénoménaux. Comme la perte de données quand la machine s'est écrasée.

8
répondu mr calendar 2015-05-31 07:55:56

Utiliser

#pragma once

en haut des fichiers d'en-tête, donc s'ils sont inclus plus d'une fois dans une unité de traduction, le texte de l'en-tête ne sera inclus et analysé qu'une seule fois.

5
répondu Scott Langham 2015-05-31 06:35:09

juste pour être complet: une construction peut être lente parce que le système de construction est stupide aussi bien que parce que le compilateur met beaucoup de temps à faire son travail.

Lire version Récursive Considéré comme Nocif (PDF) pour une discussion à ce sujet dans des environnements Unix.

5
répondu dmckee 2015-05-31 07:49:44

vous pouvez utiliser Unity Builds .

5
répondu OJ. 2016-04-25 21:42:37
  • Mise à niveau de votre ordinateur

    1. Obtenir un quad core (ou un double système quad)
    2. obtenir beaucoup de RAM.
    3. utilise un disque RAM pour réduire drastiquement les retards d'E/S des fichiers. (Il y a des entreprises qui fabriquent des disques durs IDE et SATA RAM qui agissent comme des disques durs).
  • alors vous avez toutes vos autres suggestions typiques

    1. utiliser des en-têtes précompilés si disponibles.
    2. réduisez la quantité de couplage entre les parties de votre projet. Changer un fichier d'en-tête ne devrait généralement pas requérir la recompilation de votre projet entier.
4
répondu Uhall 2008-12-16 23:34:01

j'ai eu une idée à propos de en utilisant un lecteur RAM . Il s'est avéré que pour mes projets, cela ne fait pas une grande différence après tout. Mais alors qu'ils sont assez petits encore. L'essayer! Je serais intéressé à entendre combien il a contribué.

4
répondu Vilx- 2017-05-23 11:55:19

utilisez les déclarations forward lorsque vous le pouvez. Si une déclaration de classe n'utilise qu'un pointeur ou une référence à un type, vous pouvez simplement transmettre declare it et inclure l'en-tête pour le type dans le fichier implementation.

par exemple:

// T.h
class Class2; // Forward declaration

class T {
public:
    void doSomething(Class2 &c2);
private:
    Class2 *m_Class2Ptr;
};

// T.cpp
#include "Class2.h"
void Class2::doSomething(Class2 &c2) {
    // Whatever you want here
}

moins inclut signifie beaucoup moins de travail pour le préprocesseur si vous le faites assez.

4
répondu Evan Teran 2015-05-31 21:17:03

Où passez-vous votre temps? Vous êtes relié au CPU? Lié à la mémoire? Disque lié? Pouvez-vous utiliser plus de cœurs? Plus de RAM? Avez-vous besoin de RAID? Ne vous souhaitez tout simplement améliorer l'efficacité de votre système actuel?

.

sous gcc / g++, avez-vous regardé ccache ? Il peut être utile si vous faites make_clean_;_make beaucoup.

3
répondu Mr.Ree 2008-12-17 05:30:57

liens Dynamiques (.peut être beaucoup beaucoup plus rapide que la liaison statique (.un.) Surtout quand vous avez un disque réseau lent. C'est depuis que vous avez tout le code dans le .un fichier qui doit être traité et écrit. En outre, un très grand fichier exécutable doit être écrit sur le disque.

3
répondu 2008-12-17 18:24:58

disques durs plus rapides.

compilateurs écrire beaucoup (et peut-être énorme) de fichiers sur le disque. Travailler avec SSD au lieu du disque dur typique et les temps de compilation sont beaucoup plus bas.

2
répondu linello 2013-12-16 15:33:27

sur Linux (et peut-être d'autres *NIXes), vous pouvez vraiment accélérer la compilation en ne regardant pas la sortie et en passant à un autre TTY.

Voici l'expérience: printf ralentit mon programme

2
répondu Flavius 2017-05-23 12:26:42

les parts de réseaux ralentiront drastiquement votre construction, car la latence de recherche est élevée. Pour quelque chose comme Boost, il a fait une énorme différence pour moi, même si notre lecteur de partage de réseau est assez rapide. Le temps de compiler un programme de Boost de jouet est passé d'environ 1 minute à 1 seconde quand je suis passé d'un partage de réseau à un SSD local.

2
répondu Mark Lakata 2014-04-29 18:17:59

si vous avez un processeur multicore, Visual Studio (2005 et plus tard) ainsi que GCC supportent les compilations multi-processeurs. C'est quelque chose à activer si vous avez le matériel, pour sûr.

2
répondu Peter Mortensen 2015-05-31 06:31:55

Pas sur le temps de compilation, mais sur le temps de génération:

  • Utiliser ccache si vous devez recréer les mêmes fichiers lorsque vous travaillez sur vos fichiers buildfiles

  • Utiliser ninja-construire au lieu de faire. Je suis en train de compiler un projet avec ~100 fichiers source et tout est mis en cache par ccache. faire des besoins 5 minutes, ninja moins de 1.

vous pouvez générer vos fichiers ninja à partir de cmake avec -GNinja .

2
répondu thi gg 2015-05-31 08:10:10

bien que ce ne soit pas une" technique", Je ne pouvais pas comprendre comment les projets Win32 avec de nombreux fichiers source compilés plus rapidement que mon projet vide" Hello World". Donc, j'espère que cela aide quelqu'un comme moi.

dans Visual Studio, une option pour augmenter les temps de compilation est le lien incrémental ( /INCREMENTAL ). Il est incompatible avec la génération de Code Link-time ( / LTCG ) donc rappelez-vous de désactiver la liaison incrémentale en faisant release.

1
répondu Nathan Goings 2013-09-06 17:50:05