CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

Réduction temps de compilation template C++

PillsDispenser
PillsDispenser
Niveau 67
13 août 2022 à 05:03:59

Bonjour,

J'ai un template qui est principalement utilisé avec 3 types différents.
Comment réduire le temps de compilation du programme ?

Elalilalolulu
Elalilalolulu
Niveau 4
13 août 2022 à 06:02:21

ne pas utiliser de templates :)

PillsDispenser
PillsDispenser
Niveau 67
13 août 2022 à 10:45:57

Le 13 août 2022 à 06:02:21 :
ne pas utiliser de templates :)

C'est pas la bonne réponse je pense

lokilok
lokilok
Niveau 16
13 août 2022 à 11:50:16

Tu peux instancier explicitement ces 3 types pour qu'ils ne soient compilés qu'une seule fois pour tout le programme plutôt que dans chaque translation unit : https://en.cppreference.com/w/cpp/language/class_template

Tu déclares l'instanciation explicite avec "extern" dans ton .h pour que le compilateur sache qu'il n'a pas besoin de l'instancier implicitement, puis tu définis l'instanciation explicite dans un .cpp. Tu peux aussi juste déclarer la template dans ton .h, sans la definir, comme ça au moins t'es sûr qu'il n'y aura pas d'instanciation implicite (tu auras une erreur de compilation).

Faut savoir par contre que du coup le compilateur n'aura plus accès à la définition de la template (dans les translation units hors de celle où tu fais la définition explicite, évidemment) et donc ne pourra plus faire certaines optimisations qui demandent l'accès à cette information, comme l'inlining par exemple. Sauf si tu actives la link time optimization (LTO).

Message édité le 13 août 2022 à 11:51:45 par lokilok
PillsDispenser
PillsDispenser
Niveau 67
13 août 2022 à 12:33:59

Tu peux me montrer un exemple stp

//.cpp
void SomeFunction(T foo)
{
...
}

//.h
template<typename T>
class SomeThing
{
...
void SomeFunction(T foo);
...
};

7ChipsParMinute
7ChipsParMinute
Niveau 7
13 août 2022 à 15:15:13

c'est expliqué dans le lien qu'il t'a mis

namespace N 
{
    template<class T> 
    class Y // template definition
    { 
        void mf() {} 
    }; 
}
 
template class N::Y<char*>;       // OK: explicit instantiation
template void N::Y<double>::mf(); // OK: explicit instantiation
PillsDispenser
PillsDispenser
Niveau 67
13 août 2022 à 15:52:15

Le 13 août 2022 à 15:15:13 :
c'est expliqué dans le lien qu'il t'a mis

namespace N 
{
    template<class T> 
    class Y // template definition
    { 
        void mf() {} 
    }; 
}
 
template class N::Y<char*>;       // OK: explicit instantiation
template void N::Y<double>::mf(); // OK: explicit instantiation

Du coup ca c'est dans le .h
namespace N
{
template<class T>
class Y // template definition
{
void mf() {}
};
}

Et ca dans le .cpp
template class N::Y<char*>; // OK: explicit instantiation
template void N::Y<double>::mf(); // OK: explicit instantiation

Message édité le 13 août 2022 à 15:52:35 par PillsDispenser
godrik
godrik
Niveau 30
13 août 2022 à 18:52:42

Ouais, il n'y a pas grand chose que tu puisses faire.

1/ Tu peux deplacer des parties du codes dans des unites de compilation differentes pour ne les compiler qu'une fois.
J'utilisais boost pour parser un format bibtex, et le temps de compilation de ce truc la etait monstrueux. Mais la fonction renvoyait un objet type sans template et ne prennait pas de parametre template non plus.
J'ai deplacer la fonction dans un fichier a part. Et du coup tant que je ne changais pas la facon de parser le fichier, je n'avais pas besoin de recompiler cette partie la du code. Et ca reduisait le temps de compilation pendant le developement parceque le fichier objet du parser n'etait jamais recompiler.

2/ Tu peux aussi utiliser l'explicit instanciation indiquer plus haut. Ca retire une partie des benefices de templates. Mais relativement peux, donc ca reste utilisable de facon tres generique.

3/ tu peux compiler en parallel. make -j 8 va invoquer 8 compilateurs ne meme tempos pour compiler 8 fichiers simultanement. C'est pas une solution parfaite mais ca aide!

4/ Tu peux changer de compilateur. J'ai des collegues bresiliens qui regardait comment optimiser gcc pour faire de la compilation parallele. ( https://interscity.org/assets/Improving-Parallelism-in-Git-and-GCC-Strategies-Difficulties-and-Lessons-Learned.pdf ) Mais je pense que c'est encore en developpement.

5/ Tu peux faire attention en ecrivant le code de ne pas faire des variantes pour rien.
C'est facil de se retrouver avec un

template <typename T>
void f (T i);

qui se retrouve invoque avec


f(1.0f);
f(1.0d)

Et peut etre ca fait exactement la meme chose dans ton cas d'utilisation particulier, mais ca force le compilateur a faire deux versions. Tu peux avoir des truc comme ca qui arrive avec des pointeurs ou des references ou tu te retrouve a invoquer la fonction avec des pointeurs const et des pointeurs non const. Et ca compile deux fois alors que tu ne change pas la valeure. Donc si tu cast le pointeur const a l'invocation de la fonction, tu evites de compiler deux fonctions differentes. Tu peux avoir la meme avec des unsigned.

Sous forums
  • Aide à l'achat Mac
  • Création de sites web
  • Création de Jeux
  • Linux
  • Programmation
  • Internet
  • Steam Deck
  • Macintosh
  • Hardware
La vidéo du moment