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


Vous avez aimé cette actualité ? Alors partagez-la avec vos amis en cliquant sur les boutons ci-dessous :


 Poster une réponse

Avatar de PhilIvey PhilIvey - Nouveau membre du Club https://www.developpez.com
le 25/08/2011 à 18:14
Citation Envoyé par gorgonite  Voir le message
métaprogrammation intégré au langage en C#

ok pour D (qui a "appris" des défauts de C++ ^^)

Tout depend de ta definition de la metaprogrammation , qui est possible
en C++ et D par le biais des templates.

La reflection, qui fonctionne aussi avec les generics, c'est une forme de metaprogrammation.
Avatar de gorgonite gorgonite - Rédacteur/Modérateur https://www.developpez.com
le 25/08/2011 à 20:25
Citation Envoyé par PhilIvey  Voir le message
Tout depend de ta definition de la metaprogrammation
[...]
La reflection, qui fonctionne aussi avec les generics, c'est une forme de metaprogrammation.


forcément si chacun peut définir comme il le souhaite les notions qui l'arrangent

en C#, la "reflexion" est surtout limitée à l'introspection non ?
hors, il faut aussi intercession de SmallTalk pour réellement pouvoir faire de la méta-programmation, si mes "définitions théoriques" sont correctes
Avatar de PhilIvey PhilIvey - Nouveau membre du Club https://www.developpez.com
le 25/08/2011 à 20:48
Citation Envoyé par gorgonite  Voir le message
forcément si chacun peut définir comme il le souhaite les notions qui l'arrangent

en C#, la "reflexion" est surtout limitée à l'introspection non ?
hors, il faut aussi intercession de SmallTalk pour réellement pouvoir faire de la méta-programmation, si mes "définitions théoriques" sont correctes


Il existe d'autres formes de metaprogrammation , que le template metaprogramming du c++ ( statique et compile-time)!!!

Tu as bien sur de l'introspection, mais tu peux ajouter des champs,propriétés, instancier des types génériques, des fonctions génériques, filtrer des types....
Avatar de gorgonite gorgonite - Rédacteur/Modérateur https://www.developpez.com
le 25/08/2011 à 23:01
Citation Envoyé par PhilIvey  Voir le message

Il existe d'autres formes de metaprogrammation , que le template metaprogramming du c++ ( statique et compile-time)!!!

ça fait assez peur de voir que tu ne m'as pas lu...

Citation Envoyé par PhilIvey  Voir le message
Tu as bien sur de l'introspection, mais tu peux ajouter des champs,propriétés, instancier des types génériques, des fonctions génériques, filtrer des types....


montres-moi en quoi C# est capable d'une intercession proche de SmallTalk ou Scheme, histoire que je vois ce que tu mets derrière la possibilité réelle de faire de la métaprogrammation en C#

tu parles d'une utilisation poussée du DLR ?
Avatar de Emmanuel Deloget Emmanuel Deloget - Expert confirmé https://www.developpez.com
le 26/08/2011 à 0:45
Citation Envoyé par gorgonite  Voir le message
montres-moi en quoi C# est capable d'une intercession proche de SmallTalk ou Scheme, histoire que je vois ce que tu mets derrière la possibilité réelle de faire de la métaprogrammation en C#

tu parles d'une utilisation poussée du DLR ?

Moi et la terminologie C#, ça fait 2. C'est quoi, DLR ?

Indépendamment, je pense qu'il parle surtout de la possibilité de caractériser et/ou définir du code au runtime, ce qui est possible dans une certaine mesure en C# (et en java) grâce a la réflexion. Lambda et réflexion sont capable de grandes chose .

On est effectivement loin du mécanisme des templates du C++, mais ça reste de la métaprog (puisque le principe de la métaprog, c'est le fait d'écrire du code qui va générer du code).
Avatar de oodini oodini - Membre émérite https://www.developpez.com
le 26/08/2011 à 10:11
Citation Envoyé par gorgonite  Voir le message
forcément si chacun peut définir comme il le souhaite les notions qui l'arrangent

en C#, la "reflexion" est surtout limitée à l'introspection non ?

Apparemment, Wikipedia classe bien la réflexion dans les techniques de métaprogrammation (voir arborescence à droite) :

http://en.wikipedia.org/wiki/Reflect...ter_science%29
Avatar de Niark13 Niark13 - Membre éclairé https://www.developpez.com
le 26/08/2011 à 11:08
Moi et la terminologie C#, ça fait 2. C'est quoi, DLR ?

Dynamic Language Runtime, la couche d'interopérabilité avec les langages dynamiques rajoutée dans .Net 4.0 : http://fr.wikipedia.org/wiki/Dynamic_Language_Runtime
Avatar de gorgonite gorgonite - Rédacteur/Modérateur https://www.developpez.com
le 26/08/2011 à 11:21
Citation Envoyé par oodini  Voir le message
Apparemment, Wikipedia classe bien la réflexion dans les techniques de métaprogrammation (voir arborescence à droite) :

http://en.wikipedia.org/wiki/Reflect...ter_science%29



déjà wikipedia n'est pas une source toujours fiable (mais il ne tient qu'à nous de l'améliorer ^^)

ensuite, la reflexion contient l'introspection et l'intercession, et avec juste l'introspection on est loin de la meta-programmation ^^
Avatar de PhilIvey PhilIvey - Nouveau membre du Club https://www.developpez.com
le 26/08/2011 à 11:44
Citation Envoyé par gorgonite  Voir le message
déjà wikipedia n'est pas une source toujours fiable (mais il ne tient qu'à nous de l'améliorer ^^)

ensuite, la reflexion contient l'introspection et l'intercession, et avec juste l'introspection on est loin de la meta-programmation ^^

On est un peu hors sujet,par rapport à la discussion initiale, j'ai l'impression


je connais pas le Smalltalk, donc ne serait pas comparer les possibilités d'intercession à ce qui est possible en c#.

Mais les API présentes dans Reflection.Emit, TypeBuilder et compagnie, te permettent de créer des types dynamiques, d'ajouter des champs,constructeurs,méthodes,etc...à ce type et d'obtenir une forme d'intercession, en plus de l'introspection.
Avatar de loufoque loufoque - Expert confirmé https://www.developpez.com
le 27/08/2011 à 19:10
Notre code de base est ancien,( fin des années 90), et nous avons entrepris il y a quelques années, de nettoyer certaines parties,
et de rendre l'architecture plus flexible aux modifications.

Une des solutions se basait sur Boost MPL,boost::enable_if , pour certaines factories, et Boost Fusion pour génériser les traitements en sortie de parsing.

C’était la solution la plus concise et élégante, et celle qui permettait le maximum de vérification statique du code mais l'impact sur les temps de compilation a été proprement calamiteux.

Pour te donner un indicateur très imparfait, le soft installé sur le poste client peut atteindre 10 Go...
Tout n'est pas bien sur en C++.... .

La programmation générique nécessite des connaissances et compétences particulières, et il faut savoir faire les bons compromis.
Si on ne sait pas bien s'en servir, il est très facile de faire des choses lentes et non-efficaces avec, comme avec tout autre outil de programmation.

Utiliser enable_if à tort et à travers, par exemple, c'est à éviter. La résolution de surcharge avec du SFINAE est linéaire. Elle est aussi difficilement extensible.
S'il y a des dispatch conséquents à faire, ce n'est pas le bon mécanisme. La surcharge classique avec des schémas d'héritage est à préférer, comme le fait par exemple le standard avec les tags d'itérateur.

Les tuples, c'est vraiment intéressant uniquement si les types sont différents. J'ai déjà vu du code où on utilisait des tuples où tous les éléments étaient les mêmes à la place de tableaux. Ça ralentit les temps de compil inutilement, juste pour unroller des tableaux qui le seraient de toutes manières avec un compilateur décent. Si cet unrolling n'est pas critique, autant utiliser des tableaux.

L'exécutable de 10 Go est a priori un indicateur d'une mauvaise utilisation de techniques de génération de code. Ce n'est pas une quantité de code machine normale.
Avatar de PhilIvey PhilIvey - Nouveau membre du Club https://www.developpez.com
le 28/08/2011 à 18:02
Citation Envoyé par loufoque  Voir le message

Utiliser enable_if à tort et à travers, par exemple, c'est à éviter. La résolution de surcharge avec du SFINAE est linéaire. Elle est aussi difficilement extensible.
S'il y a des dispatch conséquents à faire, ce n'est pas le bon mécanisme. La surcharge classique avec des schémas d'héritage est à préférer, comme le fait par exemple le standard avec les tags d'itérateur.

Tu as tout a fait raison. C'est la solution qui a été retenue lors de la revue de code, ie ajouter un niveau d’héritage. Je ne sais pas si c’était enable_if qui était en cause , ou plutôt toute la plomberie MPL en amont, que le gars n'avait pas optimisé. Je demanderais à l'auteur.

On a peut être eu peur à l'époque que peu de gens soient capable de le maintenir...

ça devait être en substance des choses de ce type ( avec quelque mpl::not_,mpl::or_ dans certains cas, dans certains cas plus complexes)

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 
using namespace boost::mpl; 
using namespace std; 
 
typedef copy<types1, 
	              front_inserter<types2> 
                        >::type final_types; 
						 
struct Process 
{						 
	template <typename T> 
	typename boost::enable_if<boost::mpl::contains<final_types, T>, void>::type 
	operator()(vector<string> tokens) 
	{ 
		/* 
		Traitement quelconque 
		*/ 
	} 
};
Citation Envoyé par loufoque  Voir le message

Les tuples, c'est vraiment intéressant uniquement si les types sont différents. J'ai déjà vu du code où on utilisait des tuples où tous les éléments étaient les mêmes à la place de tableaux. Ça ralentit les temps de compil inutilement, juste pour unroller des tableaux qui le seraient de toutes manières avec un compilateur décent. Si cet unrolling n'est pas critique, autant utiliser des tableaux.

Le but etait de faire du "parsing into structs"

Il y avait quelques de dizaines de structs, donc le seul point commun, était de subir des traitements quasi-identiques, avec de nombreuses combinaisons de types pour les champs, et des tailles de quelques champs à une trentaine.

C'est le cas de figure idéal pour utiliser des tuples, si on fait fi des temps de compilation.

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 
namespace TotoSpace 
{ 
	struct Toto : public TotoBase 
	{ 
		Toto(){init();} 
		string totoname; 
		long field1; 
		long field2; 
		double field3; 
	}; 
} 
 
BOOST_FUSION_ADAPT_STRUCT( 
	TotoSpace::Toto, 
		(string,totoname) 
		(long, field1) 
		(long, field2) 
		(double, field3))
BOOST_FUSION_ADAPT crée un tuple à partir des champs de la struct,
et permet d'itérer dessus.

Citation Envoyé par loufoque  Voir le message
L'exécutable de 10 Go est a priori un indicateur d'une mauvaise utilisation de techniques de génération de code. Ce n'est pas une quantité de code machine normale.


10 Go
C'est la suite logicielle avec plusieurs centaines de DDL, des dizaines d’exécutables....
Offres d'emploi IT
Data scientist senior H/F
Safran - Ile de France - Magny-les-Hameaux (Saclay)
Ingénieur H/F
Safran - Ile de France - Moissy-Cramayel (77550)
Architecte et intégrateur scade/simulink H/F
Safran - Ile de France - Vélizy-Villacoublay (78140)

Voir plus d'offres Voir la carte des offres IT
Contacter le responsable de la rubrique Accueil