Le C++ se compile-t-il trop lentement ?
Oui, répond un développeur de compilateur qui expose les raisons de cette lenteur supposée
Le 2010-08-24 13:27:31, par Idelways, Expert éminent sénior
Walter Bright travaille dans le développement de compilateurs de C++ depuis plus de 20 ans. Et selon lui c'est un fait : la compilation du C++ est lente, trop lente. Vraiment trop lente même puisqu'elle peut aller jusqu'à durer des nuits entières.
Dans un billet, il expose les raisons qui lui semblent expliquer ce problème, un problème souvent cité comme l'une des raisons qui ont motivé le développement par Google du langage de programmation « GO ».
Walter Bright expose en tout 7 raisons, autant que le nombre (important) de phases de compilations, complètement indépendantes les unes des autres.
Il explique en substance que l'appel a #include étant textuel - et non symbolique - les appels répétés aux même sources provoqueraient leur analyse complète à plusieurs reprises, même quand #include est protégé par #ifndef.
Ce mécanisme serait d'autant plus aggravé que les développeurs auraient de plus en plus tendance à « #inclure » tout (et donc aussi n'importe quoi) surtout en programmation générique et pour l'usage des templates.
Ces critiques n'empêche pas d'aimer le langage. Au contraire, il place de nombreux espoirs dans C++1x, la nouvelle norme pour le langage C++ sur laquelle planche depuis plusieurs années maintenant, un comité de normalisation ISO (et qui pourrait s'appeler C++11).
« J'espère que des efforts seront faits pour résoudre le problème », même si cela devrait prendre « au moins 10 ans » et poser des problèmes de rétrocompatibilité.
Mais quand on aime on ne compte pas... et on sait être patient.
Non ?
La compilaton du C++ est elle véritablement aussi lente que ce que laisse entendre Walter Bright ?
Quelles sont selon vous les raisons de cette lenteur ? Comment la gérez-vous ?
Est-elle préjudiciable à votre productivité ?
Avez-vous déjà envisagé de passer à Go ou un autre langage à cause de cette lenteur ?
Source : Blog Dr.Bobb's
Lire aussi :
Quel est pour vous le défaut le plus gênant du C++ ? Un développeur chevronné fait la liste des faiblesses de son langage préféré
C ou C++ ? Quel langage choisir pour un projet sur une cible embarquée ?
Le moc (meta-object compiler) a-t-il toujours une raison d'exister, maintenant que les compilateurs ont évolué ?
Les rubriques (actu, forums, tutos) de Développez :
C++
Langages
En collaboration avec Gordon Fowler
Dans un billet, il expose les raisons qui lui semblent expliquer ce problème, un problème souvent cité comme l'une des raisons qui ont motivé le développement par Google du langage de programmation « GO ».
Walter Bright expose en tout 7 raisons, autant que le nombre (important) de phases de compilations, complètement indépendantes les unes des autres.
Il explique en substance que l'appel a #include étant textuel - et non symbolique - les appels répétés aux même sources provoqueraient leur analyse complète à plusieurs reprises, même quand #include est protégé par #ifndef.
Ce mécanisme serait d'autant plus aggravé que les développeurs auraient de plus en plus tendance à « #inclure » tout (et donc aussi n'importe quoi) surtout en programmation générique et pour l'usage des templates.
Ces critiques n'empêche pas d'aimer le langage. Au contraire, il place de nombreux espoirs dans C++1x, la nouvelle norme pour le langage C++ sur laquelle planche depuis plusieurs années maintenant, un comité de normalisation ISO (et qui pourrait s'appeler C++11).
« J'espère que des efforts seront faits pour résoudre le problème », même si cela devrait prendre « au moins 10 ans » et poser des problèmes de rétrocompatibilité.
Mais quand on aime on ne compte pas... et on sait être patient.
Non ?
Source : Blog Dr.Bobb's
Lire aussi :
Les rubriques (actu, forums, tutos) de Développez :
En collaboration avec Gordon Fowler
-
Emmanuel DelogetExpert confirméC'est original comme message.
Bon, point par point :
Du coup, moins qualifié que d'autre pour parler des forces et faiblesses du langage. Le système de compilation du C++ est lent, on ne peut pas le nier, mais cette lenteur est en grande partie due aux forces intrinsèques du langage - template, etc. Du coup, ne pas connaître le langage rends l'appréciation de ses limites et des conséquences sur le modèle de compilation hasardeuse. Mais oublions ce point, car il n'a que peu d'intérêt.Et je dois bien dire que les include sont infâmes. D'ailleurs je ne comprend pas pourquoi il faut que j'indique l'usage de la classe <machin>, c'est écris dans le code, le compilo n'à qu'à lire pour le déterminer, rien de bien sorcier.
. Les seules raisons qui devraient me pousser à faire cette définition explicite seraient de vouloir forcer une version, mais d'autres mécanismes doivent déjà exister.
identifier1 identifier2;
est une déclaration de variable si identifier1 est un type, sinon une erreur de syntaxe doit être générée. Et comment savoir si identifier1 est un type ou non sans connaître le symbole ?
Le second problème est lié à la surcharge des fonctions (et des opérateurs).
c = a + b;
Peut faire intervenir deux surcharges (operator=, operator+) ainsi que des conversions implicite de type qui peuvent elles aussi être surchargées.
Par exemple :Code : 1
2
3
4
5std::string s1, s2("yy"); const char* s2 = "xx"; s1 = s2 + s3; // s1 == "yyxx"
d'utiliser des types "dynamique", mais est ce qu'on s'en sert si souvent ? Et est ce que lorsqu'on s'en sert ce n'est pas au développeur de l'indiquer explicitement.
Par ailleurs, au sein d'un même projet genre gui, pas trop gros cela va de soit, on pourrait avoir un seul include sa éviterait les duplications...
De la même manière le compilateur n'émet pas de message lorsque une librairie est chargée inutilement.
Enfin je ne comprend pas pourquoi ce genre d'update devrait attendre une dizaine d'années.... C'est pas une tâche du compilateur sa ? Suffit pas de faire un patch?....
Et faire un patch à quoi ? Au compilateur ? Lequel ? Celui d'Intel, celui de GNU, celui de Microsoft, le front end de EGC, celui de Commeau, celui de Digital Mars, celui de Codeplay, etc... ?
Ca va faire un gros patch, avec beaucoup de binaire dedans...
De mon oeil de novice qui n'y connait pas grand chose, tout cela me laisse un goût de jm'en foutisme, particulièrement lorsque je lis ceci :
le 17/08/2011 à 18:03 -
KlaimMembre expertJ'ai bossé sur un projet avec GUI et beaucoup de metaprog. qui compilait en 1h30 sur un serveur assez puissant qui nous laissait compiler avec 3 jobs (sous gcc)
Ogre (http://ogre3d.org) compile en 30 minute sur ma tour perso(AMD X2 4200+, bicore vieux de 7-8 ans), 15 minutes sur mon portable (CoreI7 QuadCore vieux de moins d'un an). Ogre ne fait QUE du rendu graphique. Mon projet sous Ogre, avec toutes les bibliothèques comprises, compile en 30 minutes sur mon portable, à froid.
Lorsque je développe, j'ai du couper le projet en beaucoup de modules (dll+application) pour limiter les compilations longues.
Au boulot, c'est pire (parcequ'on a que des bibliothèques statiques et du template a gogo).
Donc oui le problème existe.- cette lenteur est elle un vrai problème pour ceux qui travaille avec du C++ ?
Evidement!!!
Admettons que tu fasses une modification dans un header, par exemple ajuster la valeur d'une constante PI.
Tous les cpp qui, directement ou indirectement, incluent ce header seront recompilés. Tous dépends de l'utilisations masi dans certains cas ça veut dire la recompilation de toute l'application. Maintenant imagine que tu fasses une petite modif et qu'il te faille 10, 20 minutes pour voir le résultat... tu vas y perdre des journées entières. Peut être même que tu vas aller moins vite à résoudre des problèmes parcequ'entre chaque compilation tu auras oublié des détails du contexte du bug.
Enfin bref, c'est un problème crucial, le plus gros en C++ à mon avis. J'espère que le système de Modules sera vite mis en place sinon ça va être impossible même avec des machines plus puissantes, parceque la complexité des applications suit les performances.le 11/04/2011 à 14:26 -
gb_68Membre confirméVraiment ? Je vois des IDE qui sont morts
. C'est vrai qu'il y a eu un déclin, mais de là à dire que c'est mort ; on peut aussi parfois lire, le C++ c'est mort, maintenant c'est - Java, C#, D, ... (faites votre choix). Ben en C++ on fait même "pire", interface dans les .h et implémentation dans le .cpp.
Le modèle de compilation du C++ vient de son héritage du C.
Lors de la phase génération de code, les différentes unités de compilations s'ignorent complètement. Pour utiliser un élément d'une autre unité, on déclare juste l'existence du symbole (prototype pour une fonction / extern pour une variable).
C'est ensuite à l'édition des liens de s'assurer que :
- le symbole existe
- une seule unité le contient
Pour ne pas à avoir à recopier tous les symboles qu'implémente une unité, le principe des header à été mis en place : les symboles sont regroupés dans un fichier qui sera TEXTUELLEMENT recopié par le préprocesseur dans chaque unité de compilation l'incluant.
Du coup, l'on rajoute bien souvent beaucoup plus de symboles que nécessaire dans les nos unités (que le compilateur se fera une joie de reparser dans chaque unité de compilation). Si l'on se contente de prototypes et de déclarations externes, cela reste largement acceptable, ces derniers n'entrainant pas en eux-même de génération de code.
Sauf que le C++ à apporté beaucoup de fonctionnalités qui ont modifié ce mécanisme. Les fonctions inline et les templates, dont le code doit être connu à la compilation - les unités s'ignorant dans cette phase -, ont cassé la règle de l'unicité de l'unité contenant un symbole.
Résultat : un même code sera dans plusieurs unités et subira plusieurs fois certaines étapes de la compilation.
Ce mécanisme de préprocesseur à aussi permis de faire des choses intéressantes, cf. boost preprocessor, ayant elles même entrainées un nouveau surcoût (preprocessing plus long, génération de N spécialisations templates, ...).
La répétition du code dans les unités a aboutie à les rendre énormes ; et comme cela a déjà été dit dans la discussion, le langage n'est lui même pas des plus faciles à parser, ce qui n'a pas arrangé les choses.
Aujourd'hui, ce simple codeCode c++ : 1
2
3
4
5
6
7
8
9#include "stdafx.h" #include <iostream> int _tmain(int argc, _TCHAR* argv[]) { using namespace std; cout << "hello world"; return 0; }
, mais beaucoup de lignes vides) et sous VS 2010 663 Ko (74 899 lignes).
En rajoutant #include <vector>, <map>, <sstream>, je passe à 0,98 Mo (113 900 lignes). Je n'ose pas imaginer avec les bibliothèques de boost...
Si il n'est pas de envisageable de casser ce mécanisme d'inclusion, certains éléments de la nouvelle norme à venir vont tout de même permettre un allègement du traitement.
- variadic templates
-> Astuces de préprocesseur et spécialisation template en cascade qui ne seront plus nécessaires. Un temps de compilation réduit est d'ailleurs une des motivations des variadic templates - extern template
->Pour forcer l'instanciation pour un type donné dans une seule unité de compilation et non plus dans toutes celles l'utilisant.
le 27/08/2010 à 0:12 - variadic templates
-
gorgoniteRédacteur/Modérateur
tu ne comprends pas... ça se voit au premier coup d'oeil. malgré cela, tu émets des jugements (l'informatique étant le seul domaine où le premier individu passant plus d'une heure sur un ordinateur se permet d'expliquer son métier à ceux qui bossent dessus depuis des années, quoi de plus normal)
revenons à nos moutons... avant de vouloir déterminer ce qui incombe au compilateur, et ce qui doit être explicitement effectué par l'utilisateur, il faudrait déjà comprendre ce que le langage souhaite faire, vers quel public il se destine, et surtout ce que ça coûterait "d'alléger certaines étapes si ingrates aux yeux d'un novice"
déjà C++ est un langage utilisé à grande échelle, et ne dépendant pas exclusivement d'un éditeur... il y a donc un comité de "standardisation" & cie, qui empêche en théorie que tout le monde fasse n'importe quoi dans son coin, mais rien n'empêche un éditeur de s'adapter en fonction de contraintes/politiques internes dans la pratique (cf g++ 3.* , VC++ 6, etc)
les normes prennent du temps à être établies, et des guerres d'influence / de lobby / de personnes sont parfois primordiales sur l'aspect technique des "études".
donc inutile de comparer à Delphi, Java, Go & cie de ce côté... revenez à la "guerre des Pascal" à l'époque où Borland/Corel/Embarcadero (comme le KGB j'ai un peu de mal à me souvenir de son appellation du jour) ne contrôlait ce marché
après clairement, il y a des opérations purement syntaxiques à première vue inutiles... mais un bon IDE le fera pour vous
certains détails barbants subsistent, et les choses avancent à leur rythme... style auto dans C++0/1/2X (on sait jamais je prends mes précautions), l'idée des concepts qui a fini en guerre de logiciens pour un lambda-prolog dans le moteur de templates (je caricature à peine )
ok dans l'idée pour cette partiele 25/08/2010 à 12:18 -
GouyonMembre expérimentéPersonnellement j'utilise CBuilder et Visual studio et le temps de compilation ne m'a jamais paru excessif même avec des projets de 20 000 lignes codes.
D'autre part quand on parle de vitesse, il faut toujours prendre en considération la machine et les OS. Une nouvelle génération plus rapide et avec plus de mémoire apparaît presque tous les 6 mois. Alors si ça compile trop lentement attendez 6 mois et changez de machine
Malgré ça, Delphi c'est mort et quasiment enterré. Cherchez l'erreur!
le 27/08/2010 à 10:03 -
Florian GooMembre éclairéDes efforts sont faits pour résoudre le problème. Il s'agit des modules (et de la directive « import »), une proposition faite à la base pour C++0x mais pas assez mûre pour y être intégrée. Heureusement, on ne devra probablement pas avoir à attendre C++2x pour les voir arriver :
Heading for a separate TR
These topics are deemed too important to wait for another standard after C++0x before being published, but too experimental to be finalised in time for the next Standard. Therefore, these features will be delivered by a technical report at the earliest opportunity.
Voici le PDF de la proposition : http://www.open-std.org/jtc1/sc22/wg...2007/n2316.pdf
Un jour, on pourra écrire ça :
Code : 1
2
3
4import std; // Module import directive. int main() { std::cout << “Hello World\n”; }
le 08/09/2010 à 12:12 -
Florian GooMembre éclairé@bioinfornatics
Il y a quelque temps, j'ai ouvert un sujet concernant la légitimité de D à être un digne successeur du C++ : http://www.developpez.net/forums/d78...ute/langage-d/
On pourrait peut-être continuer le débat sur cet autre topic ?le 08/09/2010 à 12:49 -
HanLeeMembre éclairéMais ce n'est pas parce qu'un 100 000 lignes de code prend du temps à exécuter que ça prend du temps à être compilé.
Une boucle infinie...
Une boucle d'une ligne de calcul très lourde...
C'est peanuts à compiler!le 24/08/2010 à 14:38 -
Paul TOTHExpert éminent séniorje ne vois pas bien de quoi tu veux parler...en C++ comme en Delphi on déclare les classes on les crées et les détruit (sauf à utiliser des classes statiques en C++), mais au lieu de déclarer, initialiser et invoquer dans une même instruction, le Pascal (et donc Delphi) oblige à déclarer d'un côté, initialiser et ensuite invoquer...il est donc plus verbeux certes, mais il n'y a rien de plus ou de moins qu'en C++. D'ailleurs les propriétés dans Delphi peuvent directement faire référence à un champ privé sans avoir à déclarer des get/set
Je ne dit pas que c'est mal (je trouve le Delphi très lisible), mais Delphi est très verbeux.
Une partie de tes 100.000 ne sont QUE de la déclaration et n'effectue aucun traitement.
Cela permet à Delphi de réduire le nombre de passes, mais oblige, lors de la saisie du code, à de nombreux aller/retour entre les sections interface/implémentation - ce qui, comme des temps de compilation longs, n'est pas génial en terme de productivité (même si l'IDE aide).
Les références circulaires, sont interdite, ce qui oblige à passer par des type ancêtres générique (la VCL est plein de TObject qui dans les fait désignent des objets de bien plus haut niveau), ce qui n'est pas génial non plus.
Bref, le compilateur est rapide, mais il y a une contre-partie pour le développeur.le 26/08/2010 à 13:59 -
dlandelleMembre du ClubOn ne recompile pas tout le bordel à chaque fois non plus
Je me souviens d'un projet de 100 000 lignes de C++, bien découpé, modulaire, avec des moteurs et des plugins, c'était très rare qu'on recompile tout !
Tellement rare que le problème de vitesse de compilation ne m'est jamais apparu
Sinon la source c'est Dr Dobbs, pas Bobbs ...le 26/08/2010 à 20:59