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

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

optimiser l appel a des méthodes virtuelles


Sujet :

C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    399
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 399
    Points : 413
    Points
    413
    Par défaut optimiser l appel a des méthodes virtuelles
    Hello,

    je cherche a réduire l overhead du au polymorphisme tout en le conservant. Je m'explique :

    J'ai une classe qui sert d'interface :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    class A 
    {
    public :
     
        virtual void f(const B&) = 0;
    };
    J'ai un code de ce style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    std::vector<A*> myVectorAptr;
    std::vector<B> myVectorB;
     
    // ...
     
    for (int i = 0; i < myVectorB.size(); ++i)
        for (int j = 0; j < myVectorAptr.size(); ++j)
            myVectorAptr[j]->f(myVectorB[i]);
    Dans ce code il y a appel a une méthode virtuelle myVectorB.size() * myVectorAptr.size() fois.

    Je pourrais changer le code en :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    class A 
    {
    public :
     
        virtual void f(const std::vector<B>&) = 0;
    };
     
    // ...
     
    for (int j = 0; j < myVectorAptr.size(); ++j)
         myVectorAptr[j]->f(myVectorB);
    et faire la boucle sur les B directement dans les fonctions virtuelles et n'avoir plus que myVectorAptr.size() appels a des méthodes virtuelles mais cela impose de changer l'ordre de mes boucles. Or je ne souhaite pas le faire.

    DOnc, y a t'il moyen de faire avant les double boucles imbriquées, une premiere boucle sur myVectorAptr pour récupérer l'addresse de la méthode virtuelle a appelé en fonction du type dynamique de A, de stocker ces adresses dans un tableaux puis ainsi d'appeler les bonnes méthodes dans la double boucle sans avoir a résoudre le type dynamique de chaque A pour chaque B. Faire une sorte de vtable optimisée quoi.

    Est ce qu un mécanisme de ce genre est possible ?
    Est ce que ca réduirai l'overhead de facon significative sachant que j'ai peu de A pour beaucoup de B ?

    Je ne sais pas si je suis très clair et ma question n a peut etre pas de sens.
    Merci pour vos réponses.
    SPARK
    Moteur de particule C++ opensource avec modules de rendu OpenGL, Irrlicht et SFML

  2. #2
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    Quoi qu'il arrive, si tu veux que tous les pointeurs qui se trouvent dans myVectorAptr vérifient l'ensemble des instances qui se trouvent dans myVectorB, tu en arriveras toujours à une situation dans laquelle tu auras deux boucles imbriquées...

    Tu peux, éventuellement, faire en sorte que la deuxième boucle soit "cachée", voire, essayer d'utiliser de préférence les boucles qui travailles sur des itérateurs ou qui utilisent des plages (comme std::tr1:: / boost:: for_each ), mais tu passera toujours les myVectorB.size() éléments en revue myVectorAptr.size() fois

    Maintenant, il n'est pas exclu que l'une des solutions que j'ai esquissée ici soit plus efficace que le fait de passer par les index

    Quant à la réponse à ta question "puis-je remplacer ma fonction par...", je donnerais bien une réponse de jésuite:

    Oui, tu peux, mais quel intérêt aurais tu à le faire

    En effet, on peut raisonnablement estimer que ta variable myVectorB soit, malgré tout, un détail d'implémentation de quelque chose...

    On est donc en droit de se poser la question de savoir s'il est seulement opportun d'exposer ce genre de détail

    A l'extrême limite, je préfèrerais alors une modification proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    class A
    {
        public:
            /*cette fonction sera applicable avec  la plupart des conteneurs */
            template <Iterator>
            void f(Iterator begin, iterator end)
            {
                while(begin !=end)
                {
                    doSomething((*begin));
                    ++begin;
                }
            }
        private:
            /* déclarer la fonction en privé dans chaque classe dérivée 
             * et ne pas oublier de l'implémenter ;)
             */
           virtual void doSomething() = 0;
    }
    qui se traduirait par un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    std::vector<A*> myVectorAptr;
    std::vector<B> myVectorB;
     
    // ...
     
    for (std::vector<A*>::iterator it=myVectorAptr.begin(); 
         it < myVectorAptr.end(); ++i)
            (*it)->f(myVectorB.begin(),myVectorB.end());
    et qui ne nécessiterait pas d'exposer inutilement myVectorB en tant que tel
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  3. #3
    Membre régulier Avatar de cynique
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 60
    Points : 72
    Points
    72
    Par défaut
    En general, l'overhead d'un appel d'une fonction virtuelle est très petite, peut-être une ou deux instructions au niveau "machine".

Discussions similaires

  1. Implémentation des méthodes virtuelles en c++
    Par nosferatu dans le forum Langage
    Réponses: 3
    Dernier message: 24/03/2011, 14h37
  2. Réponses: 6
    Dernier message: 01/10/2009, 17h06
  3. Déréferencement des méthodes virtuelles
    Par jblecanard dans le forum Langage
    Réponses: 7
    Dernier message: 03/08/2009, 17h45
  4. Réponses: 6
    Dernier message: 10/10/2007, 20h11
  5. Appel d'une méthode virtuelles
    Par BIPBIP59 dans le forum C++Builder
    Réponses: 4
    Dernier message: 24/03/2006, 14h00

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo