Dans sa plupart (tous) des programmes sur lequel je travaille,
on trouve des #include a foison dans tous les sens (.h et .cpp).
Existe t'il des outils qui permettent :
- éliminer les #includes inutiles
- remplacer les #includes par des forward declarations quand c'est
possible (ou nécessaire)
- redescendre tous les #includes dans les fichier cpp
Mauvais plan : un header devrait être autosuffisant, i.e. contenir lui-même les headers dont il a besoin.
Je suis d'accord, mais il y a une assez forte tradition (au moins en C, je ne me souviens pas avoir vu du code fait par les partisants de cette tradition en C++) qui ne veut pas d'include dans d'autres include. (Voir Pikes par exemple).
Il y a, ou il y avait. Autant que je me souviens, Pike est le seul à le préconciser, et les seuls documents que j'ai vu où il le préconcise datent d'au moins quinze ans.
En d'autres termes, un .cpp contenant uniquement #include "machin.h" doit pouvoir être compilé, quelque soit le header "machin.h".
Et les entêtes précompilées et la forward declaration ?
Quel est le probleme? Tu mets les declarations qui font que ca compile plutot que d'inclure des definitions, nous sommes d'accord.
(Au fait, meme g++ et SparcWorks ont des en-tetes precompiles).
Sans le support des entêtes précompilées, le compilateur doit recompiler chaque .h, ce qui devient vite lourd quand on possède une arborescence de .h allucinante.
Je n'ai pas fait de mesure, il y a encore des compilateurs qui n'optimisent pas les gardes d'inclusion?
Autant que je sache, g++ reste le seul. Mais comment savoir ? Si tu travailles sur un disque local, ça ne fait pas de différence notable. De même si le réseau est assez rapide. (Dès que le réseau rallentit un peu, en révance...)
-- James Kanze GABI Software Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Mauvais plan : un header devrait être autosuffisant, i.e.
contenir lui-même les headers dont il a besoin.
Je suis d'accord, mais il y a une assez forte tradition (au
moins en C, je ne me souviens pas avoir vu du code fait par
les partisants de cette tradition en C++) qui ne veut pas
d'include dans d'autres include. (Voir Pikes par exemple).
Il y a, ou il y avait. Autant que je me souviens, Pike est le
seul à le préconciser, et les seuls documents que j'ai vu où il
le préconcise datent d'au moins quinze ans.
En d'autres termes, un .cpp contenant uniquement #include
"machin.h" doit pouvoir être compilé, quelque soit le
header "machin.h".
Et les entêtes précompilées et la forward declaration ?
Quel est le probleme? Tu mets les declarations qui font que
ca compile plutot que d'inclure des definitions, nous sommes
d'accord.
(Au fait, meme g++ et SparcWorks ont des en-tetes
precompiles).
Sans le support des entêtes précompilées, le compilateur
doit recompiler chaque .h, ce qui devient vite lourd quand
on possède une arborescence de .h allucinante.
Je n'ai pas fait de mesure, il y a encore des compilateurs qui
n'optimisent pas les gardes d'inclusion?
Autant que je sache, g++ reste le seul. Mais comment savoir ? Si
tu travailles sur un disque local, ça ne fait pas de différence
notable. De même si le réseau est assez rapide. (Dès que le
réseau rallentit un peu, en révance...)
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Mauvais plan : un header devrait être autosuffisant, i.e. contenir lui-même les headers dont il a besoin.
Je suis d'accord, mais il y a une assez forte tradition (au moins en C, je ne me souviens pas avoir vu du code fait par les partisants de cette tradition en C++) qui ne veut pas d'include dans d'autres include. (Voir Pikes par exemple).
Il y a, ou il y avait. Autant que je me souviens, Pike est le seul à le préconciser, et les seuls documents que j'ai vu où il le préconcise datent d'au moins quinze ans.
En d'autres termes, un .cpp contenant uniquement #include "machin.h" doit pouvoir être compilé, quelque soit le header "machin.h".
Et les entêtes précompilées et la forward declaration ?
Quel est le probleme? Tu mets les declarations qui font que ca compile plutot que d'inclure des definitions, nous sommes d'accord.
(Au fait, meme g++ et SparcWorks ont des en-tetes precompiles).
Sans le support des entêtes précompilées, le compilateur doit recompiler chaque .h, ce qui devient vite lourd quand on possède une arborescence de .h allucinante.
Je n'ai pas fait de mesure, il y a encore des compilateurs qui n'optimisent pas les gardes d'inclusion?
Autant que je sache, g++ reste le seul. Mais comment savoir ? Si tu travailles sur un disque local, ça ne fait pas de différence notable. De même si le réseau est assez rapide. (Dès que le réseau rallentit un peu, en révance...)
-- James Kanze GABI Software Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jean-Marc Bourguet
"kanze" writes:
Jean-Marc Bourguet wrote:
Stephane Wirtel writes:
Mauvais plan : un header devrait être autosuffisant, i.e. contenir lui-même les headers dont il a besoin.
Je suis d'accord, mais il y a une assez forte tradition (au moins en C, je ne me souviens pas avoir vu du code fait par les partisants de cette tradition en C++) qui ne veut pas d'include dans d'autres include. (Voir Pikes par exemple).
Il y a, ou il y avait. Autant que je me souviens, Pike est le seul à le préconciser, et les seuls documents que j'ai vu où il le préconcise datent d'au moins quinze ans.
Il me semble que j'en ai encore vu il y a 5 ou 6 ans.
Je n'ai pas fait de mesure, il y a encore des compilateurs qui J'ai oublie ^recemment
n'optimisent pas les gardes d'inclusion?
Autant que je sache, g++ reste le seul. Mais comment savoir ? Si tu travailles sur un disque local, ça ne fait pas de différence notable. De même si le réseau est assez rapide. (Dès que le réseau rallentit un peu, en révance...)
J'ai le souvenir de l'avoir mesure pour SparcWorks et il me semble -- mais j'avoue que ta reaction me fait douter -- que le resultat etait qu'il avait cette optimisation.
A+
-- Jean-Marc FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html Site de usenet-fr: http://www.usenet-fr.news.eu.org
Mauvais plan : un header devrait être autosuffisant, i.e.
contenir lui-même les headers dont il a besoin.
Je suis d'accord, mais il y a une assez forte tradition (au
moins en C, je ne me souviens pas avoir vu du code fait par
les partisants de cette tradition en C++) qui ne veut pas
d'include dans d'autres include. (Voir Pikes par exemple).
Il y a, ou il y avait. Autant que je me souviens, Pike est le
seul à le préconciser, et les seuls documents que j'ai vu où il
le préconcise datent d'au moins quinze ans.
Il me semble que j'en ai encore vu il y a 5 ou 6 ans.
Je n'ai pas fait de mesure, il y a encore des compilateurs qui
J'ai oublie ^recemment
n'optimisent pas les gardes d'inclusion?
Autant que je sache, g++ reste le seul. Mais comment savoir ? Si tu
travailles sur un disque local, ça ne fait pas de différence
notable. De même si le réseau est assez rapide. (Dès que le réseau
rallentit un peu, en révance...)
J'ai le souvenir de l'avoir mesure pour SparcWorks et il me semble --
mais j'avoue que ta reaction me fait douter -- que le resultat etait
qu'il avait cette optimisation.
A+
--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Mauvais plan : un header devrait être autosuffisant, i.e. contenir lui-même les headers dont il a besoin.
Je suis d'accord, mais il y a une assez forte tradition (au moins en C, je ne me souviens pas avoir vu du code fait par les partisants de cette tradition en C++) qui ne veut pas d'include dans d'autres include. (Voir Pikes par exemple).
Il y a, ou il y avait. Autant que je me souviens, Pike est le seul à le préconciser, et les seuls documents que j'ai vu où il le préconcise datent d'au moins quinze ans.
Il me semble que j'en ai encore vu il y a 5 ou 6 ans.
Je n'ai pas fait de mesure, il y a encore des compilateurs qui J'ai oublie ^recemment
n'optimisent pas les gardes d'inclusion?
Autant que je sache, g++ reste le seul. Mais comment savoir ? Si tu travailles sur un disque local, ça ne fait pas de différence notable. De même si le réseau est assez rapide. (Dès que le réseau rallentit un peu, en révance...)
J'ai le souvenir de l'avoir mesure pour SparcWorks et il me semble -- mais j'avoue que ta reaction me fait douter -- que le resultat etait qu'il avait cette optimisation.
A+
-- Jean-Marc FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html Site de usenet-fr: http://www.usenet-fr.news.eu.org
kanze
Jean-Marc Bourguet wrote:
"kanze" writes:
Jean-Marc Bourguet wrote:
Stephane Wirtel writes:
Mauvais plan : un header devrait être autosuffisant, i.e. contenir lui-même les headers dont il a besoin.
Je suis d'accord, mais il y a une assez forte tradition (au moins en C, je ne me souviens pas avoir vu du code fait par les partisants de cette tradition en C++) qui ne veut pas d'include dans d'autres include. (Voir Pikes par exemple).
Il y a, ou il y avait. Autant que je me souviens, Pike est le seul à le préconciser, et les seuls documents que j'ai vu où il le préconcise datent d'au moins quinze ans.
Il me semble que j'en ai encore vu il y a 5 ou 6 ans.
J'ai vu l'article de Pike hier -- il est disponible sur la toile à http://www.quut.com/c/pikestyle.html. Mais il porte la date de 21 février, 1989.
Rémarque, même en 1989, ce conseil me semble daté.
Il se justifiait un peu avec de très anciens compilateurs, qui avait des limites assez basses sur le niveau d'embrication des includes ; dans les premiers Unix, le nombre maximum de fichiers ouverts simultanément était quelque chose comme 19 ou 20. Tu enlèves trois pour les trois entrées/sorties standards, puis le fichier de sortie et des fichiers intermédiaires (du fait que le compilateur ne pouvait pas tenir tout en mémoire), etc., et il n'en restait plus tellement. Et j'ai l'impression que certains compilateurs le limitaient encore plus, de façon artificielle ; je me suis déjà servi d'un compilateur C qui le limitait à six, est j'ai entendu parler (comme ça, alors je ne sais pas si c'est vrai) d'un qui le limitait à trois.
Je n'ai pas fait de mesure, il y a encore des compilateurs qui J'ai oublie ^recemment
n'optimisent pas les gardes d'inclusion?
Autant que je sache, g++ reste le seul. Mais comment savoir ? Si tu travailles sur un disque local, ça ne fait pas de différence notable. De même si le réseau est assez rapide. (Dès que le réseau rallentit un peu, en révance...)
J'ai le souvenir de l'avoir mesure pour SparcWorks et il me semble -- mais j'avoue que ta reaction me fait douter -- que le resultat etait qu'il avait cette optimisation.
Comment faire pour le mesurer, ou pour savoir, sans instrumenter le système ?
Je sais que j'en ai parlé avec Steve Clamage (du groupe des compilateurs chez Sun) il y a longtemps, et il m'a dit qu'ils l'avaient considéré, mais qu'ils avaient fait des mesures, et que ça ne rapportait rien ; un open et la lecture du fichier sous Solaris était tellement rapide. Je ne connais pas la contexte où ils ont fait ces mesures, mais à la même époque, nous avons fait des essais, avec Sun CC, et on a trouvé des différences énormes. Seulement, à l'époque, on avait un réseau extrèmement lent et surchargé, et lors de nos essais, tous les fichiers étaient montés sur NFS. J'ai conclu que c'était l'explication de la différence dans nos mesures.
Les choses ont bien pû évoluer depuis. Seulement, je m'attendrais à ce que l'évolution va dans l'autre sens : les réseaux devient plus rapides, on compile de plus en plus souvent contre des disques locaux, et la compilation elle-même devient plus complexe, ce qui reduit l'importance des temps de lecture dans le temps total de compilation. Tout ce qui tend à rendre l'optimisation encore moins importante.
Mais peut-être aussi qu'ils ont refait des mesures, avec d'autres résultats, et décidé en effet que ça vaut la peine. Ce que je peux dire, c'est qu'entre la version 5.1 et la version 5.5 du compilateur, les temps de compilation ont améliorés nettement -- d'environs quatres heures pour un build complet de ma bibliothèqu, à moins d'une heure et démi. (Dans le même temps, g++ a passé de moins d'une heure à une heure trois quart. Mais ça s'explique au moins partiellement par le passage des iostream classiques au iostream standard -- il faut beaucoup plus de temps pour compiler les en-têtes avec des templates que sans.)
-- James Kanze GABI Software Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Mauvais plan : un header devrait être autosuffisant,
i.e. contenir lui-même les headers dont il a besoin.
Je suis d'accord, mais il y a une assez forte tradition
(au moins en C, je ne me souviens pas avoir vu du code
fait par les partisants de cette tradition en C++) qui ne
veut pas d'include dans d'autres include. (Voir Pikes par
exemple).
Il y a, ou il y avait. Autant que je me souviens, Pike est
le seul à le préconciser, et les seuls documents que j'ai vu
où il le préconcise datent d'au moins quinze ans.
Il me semble que j'en ai encore vu il y a 5 ou 6 ans.
J'ai vu l'article de Pike hier -- il est disponible sur la toile
à http://www.quut.com/c/pikestyle.html. Mais il porte la date de
21 février, 1989.
Rémarque, même en 1989, ce conseil me semble daté.
Il se justifiait un peu avec de très anciens compilateurs, qui
avait des limites assez basses sur le niveau d'embrication des
includes ; dans les premiers Unix, le nombre maximum de fichiers
ouverts simultanément était quelque chose comme 19 ou 20. Tu
enlèves trois pour les trois entrées/sorties standards, puis le
fichier de sortie et des fichiers intermédiaires (du fait que le
compilateur ne pouvait pas tenir tout en mémoire), etc., et il
n'en restait plus tellement. Et j'ai l'impression que certains
compilateurs le limitaient encore plus, de façon artificielle ;
je me suis déjà servi d'un compilateur C qui le limitait à six,
est j'ai entendu parler (comme ça, alors je ne sais pas si
c'est vrai) d'un qui le limitait à trois.
Je n'ai pas fait de mesure, il y a encore des compilateurs qui
J'ai oublie ^recemment
n'optimisent pas les gardes d'inclusion?
Autant que je sache, g++ reste le seul. Mais comment savoir
? Si tu travailles sur un disque local, ça ne fait pas de
différence notable. De même si le réseau est assez rapide.
(Dès que le réseau rallentit un peu, en révance...)
J'ai le souvenir de l'avoir mesure pour SparcWorks et il me
semble -- mais j'avoue que ta reaction me fait douter -- que
le resultat etait qu'il avait cette optimisation.
Comment faire pour le mesurer, ou pour savoir, sans instrumenter
le système ?
Je sais que j'en ai parlé avec Steve Clamage (du groupe des
compilateurs chez Sun) il y a longtemps, et il m'a dit qu'ils
l'avaient considéré, mais qu'ils avaient fait des mesures, et
que ça ne rapportait rien ; un open et la lecture du fichier
sous Solaris était tellement rapide. Je ne connais pas la
contexte où ils ont fait ces mesures, mais à la même époque,
nous avons fait des essais, avec Sun CC, et on a trouvé des
différences énormes. Seulement, à l'époque, on avait un réseau
extrèmement lent et surchargé, et lors de nos essais, tous les
fichiers étaient montés sur NFS. J'ai conclu que c'était
l'explication de la différence dans nos mesures.
Les choses ont bien pû évoluer depuis. Seulement, je
m'attendrais à ce que l'évolution va dans l'autre sens : les
réseaux devient plus rapides, on compile de plus en plus souvent
contre des disques locaux, et la compilation elle-même devient
plus complexe, ce qui reduit l'importance des temps de lecture
dans le temps total de compilation. Tout ce qui tend à rendre
l'optimisation encore moins importante.
Mais peut-être aussi qu'ils ont refait des mesures, avec
d'autres résultats, et décidé en effet que ça vaut la peine. Ce
que je peux dire, c'est qu'entre la version 5.1 et la version
5.5 du compilateur, les temps de compilation ont améliorés
nettement -- d'environs quatres heures pour un build complet de
ma bibliothèqu, à moins d'une heure et démi. (Dans le même
temps, g++ a passé de moins d'une heure à une heure trois quart.
Mais ça s'explique au moins partiellement par le passage des
iostream classiques au iostream standard -- il faut beaucoup
plus de temps pour compiler les en-têtes avec des templates que
sans.)
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Mauvais plan : un header devrait être autosuffisant, i.e. contenir lui-même les headers dont il a besoin.
Je suis d'accord, mais il y a une assez forte tradition (au moins en C, je ne me souviens pas avoir vu du code fait par les partisants de cette tradition en C++) qui ne veut pas d'include dans d'autres include. (Voir Pikes par exemple).
Il y a, ou il y avait. Autant que je me souviens, Pike est le seul à le préconciser, et les seuls documents que j'ai vu où il le préconcise datent d'au moins quinze ans.
Il me semble que j'en ai encore vu il y a 5 ou 6 ans.
J'ai vu l'article de Pike hier -- il est disponible sur la toile à http://www.quut.com/c/pikestyle.html. Mais il porte la date de 21 février, 1989.
Rémarque, même en 1989, ce conseil me semble daté.
Il se justifiait un peu avec de très anciens compilateurs, qui avait des limites assez basses sur le niveau d'embrication des includes ; dans les premiers Unix, le nombre maximum de fichiers ouverts simultanément était quelque chose comme 19 ou 20. Tu enlèves trois pour les trois entrées/sorties standards, puis le fichier de sortie et des fichiers intermédiaires (du fait que le compilateur ne pouvait pas tenir tout en mémoire), etc., et il n'en restait plus tellement. Et j'ai l'impression que certains compilateurs le limitaient encore plus, de façon artificielle ; je me suis déjà servi d'un compilateur C qui le limitait à six, est j'ai entendu parler (comme ça, alors je ne sais pas si c'est vrai) d'un qui le limitait à trois.
Je n'ai pas fait de mesure, il y a encore des compilateurs qui J'ai oublie ^recemment
n'optimisent pas les gardes d'inclusion?
Autant que je sache, g++ reste le seul. Mais comment savoir ? Si tu travailles sur un disque local, ça ne fait pas de différence notable. De même si le réseau est assez rapide. (Dès que le réseau rallentit un peu, en révance...)
J'ai le souvenir de l'avoir mesure pour SparcWorks et il me semble -- mais j'avoue que ta reaction me fait douter -- que le resultat etait qu'il avait cette optimisation.
Comment faire pour le mesurer, ou pour savoir, sans instrumenter le système ?
Je sais que j'en ai parlé avec Steve Clamage (du groupe des compilateurs chez Sun) il y a longtemps, et il m'a dit qu'ils l'avaient considéré, mais qu'ils avaient fait des mesures, et que ça ne rapportait rien ; un open et la lecture du fichier sous Solaris était tellement rapide. Je ne connais pas la contexte où ils ont fait ces mesures, mais à la même époque, nous avons fait des essais, avec Sun CC, et on a trouvé des différences énormes. Seulement, à l'époque, on avait un réseau extrèmement lent et surchargé, et lors de nos essais, tous les fichiers étaient montés sur NFS. J'ai conclu que c'était l'explication de la différence dans nos mesures.
Les choses ont bien pû évoluer depuis. Seulement, je m'attendrais à ce que l'évolution va dans l'autre sens : les réseaux devient plus rapides, on compile de plus en plus souvent contre des disques locaux, et la compilation elle-même devient plus complexe, ce qui reduit l'importance des temps de lecture dans le temps total de compilation. Tout ce qui tend à rendre l'optimisation encore moins importante.
Mais peut-être aussi qu'ils ont refait des mesures, avec d'autres résultats, et décidé en effet que ça vaut la peine. Ce que je peux dire, c'est qu'entre la version 5.1 et la version 5.5 du compilateur, les temps de compilation ont améliorés nettement -- d'environs quatres heures pour un build complet de ma bibliothèqu, à moins d'une heure et démi. (Dans le même temps, g++ a passé de moins d'une heure à une heure trois quart. Mais ça s'explique au moins partiellement par le passage des iostream classiques au iostream standard -- il faut beaucoup plus de temps pour compiler les en-têtes avec des templates que sans.)
-- James Kanze GABI Software Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34