IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

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 , par Idelways

42PARTAGES

0  1 
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

Une erreur dans cette actualité ? Signalez-nous-la !

Avatar de Emmanuel Deloget
Expert confirmé https://www.developpez.com
Le 17/08/2011 à 18:03
Citation Envoyé par kaymak Voir le message
Je ne suis pas un spécialiste barbu du c++, juste un nouvel utilisateur depuis peu, quelques heures à mon actif.

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.

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?....

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 :

a plus
C'est original comme message.

Bon, point par point :

Citation Envoyé par kaymak Voir le message

Je ne suis pas un spécialiste barbu du c++, juste un nouvel utilisateur depuis peu, quelques heures à mon actif.
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.
Impossible au vu du modèle de compilation. Un élément qui n'est pas déclarer avant d'être utilisé est impossible à identifier correctement avant la phase de lien, ce qui n'est pas une bonne chose (ça reviendrais à compiler systématiquement tout le projet avant de pouvoir détecter 90% des erreurs). Ce n'est pas acceptable - d'où la présence des headers (qui ne contiennent pas que des classes, et qui peuvent contenir plusieurs classes si nécessaire ; de plus, la classe machin n'est pas nécessairement définie dans <machin>.

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.
Nope. La raison est la validation syntaxique du code. Deux problèmes sont à résoudre : la grammaire ambigüe du C++ fait que des expressions semblables peuvent avoir un traitement fort différent selon le type des symboles utilisé, ou que certaines expressions n'ont pas de sens.

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 : Sélectionner tout
1
2
3
4
5
std::string s1, s2("yy"); 
const char* s2 = "xx";

s1 = s2 + s3;
// s1 == "yyxx"
Comment le compilateur peut-il savoir s'il doit générer du code pour une addition (opcode assembleur ADD ou assimilé) ou s'il doit appeler une fonction (CALL) ? S'il veut pouvoir faire le choix, il lui faut connaître le détail des types utilisé. Sans header, cela reviendrait à réécrire le header de manière systématique dans tous les fichiers qui l'utilise.


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...
Je ne comprends pas ce que tu veux dire.


De la même manière le compilateur n'émet pas de message lorsque une librairie est chargée inutilement.
Pour la simple et bonne raison que c'est au linker de le faire, et pas au compilateur. Ca ne fait pas partie du langage. Le compilateur a simplement pour but d'interpréter correctement le programme, et de générer une sortie qui sera comprise par le linker. Le reste est du ressort d'autres outils de la chaine qui n'ont rien à voir avec le C++ (le linker GNU (ld) est utilisé par d'autres toolchain : C, fortran, pascal,...).


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?....
Euh... J'ai du mal à comprendre ce passage. La mise à jour de la norme C++ est suffisamment importante pour avoir nécessité des années de travail. Sans cette norme, aucun compilateur ne fonctionnerait de la même manière et les programmes C++ ne seraient pas portables d'un compilateur à l'autre. Ce n'est pas à un vendeur de compilateur de dicter sa loi sur le marché, surtout lorsque le langage ne lui appartient pas (il peut le faire s'il veut, mais il va développer son produit en pure perte : personne de censé ne l’achètera).

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 fait que les plus grand experts du monde se soient penchés pendant 10 ans sur le problème de le mise à jour du standard du C++ te laisse un goût de "jm'en foutisme"? Il faudrait peut être que tu ailles les aider alors, parce que ça, ça me laisse sans voix.
8  0 
Avatar de Klaim
Membre expert https://www.developpez.com
Le 11/04/2011 à 14:26
Citation Envoyé par Sunchaser Voir le message
Bonsoir,

- y a t il une "vraie" lenteur lors de la compilation de projets importants/complexes/lourds (appelez ca comme vous voulez) en C++ ?
J'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.
5  0 
Avatar de gb_68
Membre confirmé https://www.developpez.com
Le 27/08/2010 à 0:12
Citation Envoyé par Aurelien.Regat-Barrel  Voir le message
Malgré ça, Delphi c'est mort et quasiment enterré. Cherchez l'erreur!

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).

Citation Envoyé par vanquish  Voir le message
à de nombreux aller/retour entre les sections interface/implémentation

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 code
Code c++ : Sélectionner tout
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; 
}
donne sous VS 2005, après préprocesseur, un fichier de 565 Ko (54 458 lignes , 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.
4  0 
Avatar de gorgonite
Rédacteur/Modérateur https://www.developpez.com
Le 25/08/2010 à 12:18
Citation Envoyé par kaymak Voir le message
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.

...

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?....

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 :

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 )

Citation Envoyé par kaymak Voir le message

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.
ok dans l'idée pour cette partie
3  0 
Avatar de Gouyon
Membre expérimenté https://www.developpez.com
Le 27/08/2010 à 10:03
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!
Alors là pas d'accord du tout voire l'activité Delphi sur le site.
3  0 
Avatar de Florian Goo
Membre éclairé https://www.developpez.com
Le 08/09/2010 à 12:12
Citation Envoyé par Idelways Voir le message
« 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é.
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.
Source : http://www.open-std.org/jtc1/sc22/wg...009/n2869.html

Voici le PDF de la proposition : http://www.open-std.org/jtc1/sc22/wg...2007/n2316.pdf

Un jour, on pourra écrire ça :
Code : Sélectionner tout
1
2
3
4
import std; // Module import directive.
int main() {
    std::cout << “Hello World\n”;
}
2  0 
Avatar de Florian Goo
Membre éclairé https://www.developpez.com
Le 08/09/2010 à 12:49
@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 ?
3  1 
Avatar de HanLee
Membre éclairé https://www.developpez.com
Le 24/08/2010 à 14:38
Citation Envoyé par HAL-9000 Voir le message
@ chaplin : la longueur de code ne fait pas tout... 100 000 lignes dont l'objectif est d'afficher la valeur 1 au moniteur c'est pas la même que 100 000 lignes qui calibrent, modélisent et simulent des modèles mathématiques.
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!
1  0 
Avatar de Paul TOTH
Expert éminent sénior https://www.developpez.com
Le 26/08/2010 à 13:59
Citation Envoyé par vanquish Voir le message
Bonjour,

C'est aussi parce qu'en Delphi, le développeur se cogne une grosse part du boulot, fait par le compilateur dans les autres langages.

je 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.
que ce soit de la déclaration ou du code, se serra toujours plus rapide à compiler sous Delphi que le même code C++ car le compilateur sait toujours à quoi il a affaire...en c++ on pourra toujours tomber sur une référence externe ambiguë ou non résolue au moment de l'édition de liens.


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).
l'IDE offre en effet bon nombre de raccourcis pour ce point (Ctrl + Alt + C et hop ! l'interface est reportée en implementation)


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.
c'est un prix que j'accepte pour une compilation ultra rapide, et c'est un point qui me pose très rarement problème


Bref, le compilateur est rapide, mais il y a une contre-partie pour le développeur.
Il n'est pas "que" rapide : une compilation de plusieurs heures sous Delphi ça n'existe pas ! Et c'est ce rapport gain de compilation/perte en déclaration qui me fait préférer de loin le Pascal aux autres langages compilés.
3  2 
Avatar de dlandelle
Membre du Club https://www.developpez.com
Le 26/08/2010 à 20:59
On 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 ...
1  0