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 :

Différence de performances dans l'appel d'une fonction virtuelle


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif
    Profil pro
    Dev
    Inscrit en
    Mai 2009
    Messages
    257
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Dev

    Informations forums :
    Inscription : Mai 2009
    Messages : 257
    Par défaut Différence de performances dans l'appel d'une fonction virtuelle
    Bonsoir

    Je n'arrive pas à m'expliquer la différence de temps d'exécution entre l'appel direct d'une méthode virtuelle sur une classe et l'appel délégué de cette même méthode virtuelle à partir d'une autre classe

    pour information, je suis sous gcc 4.5.1 (g++ -std=c++0x -O2)
    sous Ubuntu 10.04

    le code :

    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
     
    #include <iostream>
    #include <string>
    #include <memory>
    #include <chrono>
    #include <vector>
    using namespace std;
     
    class Print{
     
    public:
     
    virtual void print(int p1, float p2, float p3, float p4){}
     
    };
     
    class PrintWrapper
    {
     
        public:
     
          PrintWrapper(shared_ptr<Print> print, int p1, float p2, float p3, float p4) :
          m_print(print), _p1(p1),_p2(p2),_p3(p3),_p4(p4){}
     
          ~PrintWrapper(){}
     
          void execute()
          { 
            m_print->print(_p1,_p2,_p3,_p4); 
          }
     
        private:
     
          shared_ptr<Print> m_print;
          int _p1;
          float _p2,_p3,_p4;
     
    };
     
    void test()
    {
     shared_ptr<Print> p(new Print());
     shared_ptr<PrintWrapper> pw(new PrintWrapper(p, 1, 2.f,3.0f,4.0f));
     
     //-------------test 1-------------------------
     auto time1 = std::chrono::system_clock::now();
     
     for (auto var = 0; var < 1000000; ++var) 
     {
       p->print(1, 2.f,3.0f,4.0f);
     }
     
     auto time2 = std::chrono::system_clock::now();
     
     cout <<"test 1 : "<< (time2 - time1).count() << " microseconds." << endl;
     
      //-------------test 2-------------------------
     auto time3 = std::chrono::system_clock::now();
     
     for (auto var = 0; var < 1000000; ++var) 
     {
       pw->execute();
     }
     
     auto time4 = std::chrono::system_clock::now();
     
     cout <<"test 2 : "<< (time4 - time3).count() << " microseconds." << endl;
     
    }
    int main() { test(); }
    verdict :

    test 1 : 3494 microseconds.
    test 2 : 5888 microseconds.

    soit plus de 60% de différence ! comment l'expliquer ? bien sûr print ne fait rien mais quand même...

    dans le doute j'ai testé également avec ideone (même niveau d'optimisation) :

    http://ideone.com/p3hjp

    même résultats

  2. #2
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    Tu fais trop peu d'itérations pour que ce soit pertinant (lances le test plusieurs fois, tu verras les résultats varier), passes à 1 000 000 000 itérations. Personnelement j'obtients une différence de quelques % (5% environ).

  3. #3
    Membre très actif
    Profil pro
    Dev
    Inscrit en
    Mai 2009
    Messages
    257
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Dev

    Informations forums :
    Inscription : Mai 2009
    Messages : 257
    Par défaut
    Citation Envoyé par Flob90 Voir le message
    Tu fais trop peu d'itérations pour que ce soit pertinant (lances le test plusieurs fois, tu verras les résultats varier), passes à 1 000 000 000 itérations. Personnelement j'obtients une différence de quelques % (5% environ).
    je ne sais pas comment tu t'y est pris chez toi mais je viens de refaire le test avec 100 000 000 itérations sur ideone (au delà le temps d’exécution max est dépassé) et le rapport n'a pas changé :

    test 1 : 350116 microseconds.
    test 2 : 589507 microseconds.

    c'est quand même embêtant cette histoire, si même le simple fait d’appeler une méthode virtuelle depuis une classe engendre un overhead, je n'ose pas imaginer ce que cela donne quand on a une dizaine d'appels virtuels imbriqués

  4. #4
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    J'ai testé en -O2 (ca marche même en -O1), ideone ne doit pas compiler en optimisé. Refais le test sur ta propre machine.

  5. #5
    Membre très actif
    Profil pro
    Dev
    Inscrit en
    Mai 2009
    Messages
    257
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Dev

    Informations forums :
    Inscription : Mai 2009
    Messages : 257
    Par défaut
    Citation Envoyé par Flob90 Voir le message
    J'ai testé en -O2 (ca marche même en -O1), ideone ne doit pas compiler en optimisé. Refais le test sur ta propre machine.
    j'ai refait le test avec toutes les optimisations possibles et j'aboutis au même résultat

    je veux juste savoir si c'est qqchose de normal

  6. #6
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    Il y a un niveau d'indirection supplémentaire. C'est ça que tu mesures.

    Les compteurs (et en particulier les atomiques), ce n'est pas gratuit. (EDIT: mais pas applicable ici ; c'est plutôt l'indirection qui rajoute une assertion qui est mesurée)
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  7. #7
    Membre très actif
    Profil pro
    Dev
    Inscrit en
    Mai 2009
    Messages
    257
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Dev

    Informations forums :
    Inscription : Mai 2009
    Messages : 257
    Par défaut
    Citation Envoyé par Luc Hermitte Voir le message
    Il y a un niveau d'indirection supplémentaire. C'est ça que tu mesures.
    Les compteurs (et en particulier les atomiques), ce n'est pas gratuit.
    ou ça ? dans chacun des tests j’appelle la méthode virtuelle, sauf que dans le deuxième je le fait à partir de méthode (non virtuelle) d'une classe

    aucun niveau d'indirection supplémentaire là-dedans

  8. #8
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Salut,
    souvent compilateur varie ...

    j'ai rajouté une boucle dans ton main pour répéter 10x l'appel à test et j'ai changé la constante à 100 000 000.

    Visual C++ (- /O2 /Ot):
    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    test 1 : 3930000 microseconds.
    test 2 : 3440000 microseconds.
     
    test 1 : 3870000 microseconds.
    test 2 : 3460000 microseconds.
     
    test 1 : 4850000 microseconds.
    test 2 : 3910000 microseconds.
     
    test 1 : 4550000 microseconds.
    test 2 : 4210000 microseconds.
     
    test 1 : 4530000 microseconds.
    test 2 : 3430000 microseconds.
     
    test 1 : 3820000 microseconds.
    test 2 : 3390000 microseconds.
     
    test 1 : 3860000 microseconds.
    test 2 : 3400000 microseconds.
     
    test 1 : 3820000 microseconds.
    test 2 : 3390000 microseconds.
     
    test 1 : 3860000 microseconds.
    test 2 : 3390000 microseconds.
     
    test 1 : 3830000 microseconds.
    test 2 : 3400000 microseconds.
     
    Appuyez sur une touche pour continuer...
    MinGW (gcc 4.6.1) (-fexpensive-optimizations -O2)
    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    test 1 : 442000 microseconds.
    test 2 : 567000 microseconds.
     
    test 1 : 438000 microseconds.
    test 2 : 581000 microseconds.
     
    test 1 : 561000 microseconds.
    test 2 : 727000 microseconds.
     
    test 1 : 439000 microseconds.
    test 2 : 556000 microseconds.
     
    test 1 : 437000 microseconds.
    test 2 : 556000 microseconds.
     
    test 1 : 428000 microseconds.
    test 2 : 556000 microseconds.
     
    test 1 : 432000 microseconds.
    test 2 : 557000 microseconds.
     
    test 1 : 434000 microseconds.
    test 2 : 556000 microseconds.
     
    test 1 : 428000 microseconds.
    test 2 : 553000 microseconds.
     
    test 1 : 427000 microseconds.
    test 2 : 557000 microseconds.
     
     
    Process returned 0 (0x0)   execution time : 10.309 s
    Press any key to continue.
    Difficile de tirer une conclusion...

  9. #9
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    Bha oui :
    Cas 1 : p -> operator-> -> print
    Cas 2 : p -> operator-> -> execute -> operator-> -> print

    Tu as toujours +60% avec gcc en O3 et 1000000000 sur ta propre machine ? Si c'est le cas c'est vraiment étrange ...

    @3DArchi: Une conclusion franche peut-être pas, mais on voit que t'es quand même pas à une différence de 60%.

Discussions similaires

  1. Espace dans l'appel d'une fonction
    Par pierre50 dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 09/12/2007, 11h19
  2. Variable en option dans l'appel d'une fonction
    Par xian21 dans le forum ASP.NET
    Réponses: 7
    Dernier message: 19/11/2007, 15h13
  3. Réponses: 4
    Dernier message: 30/08/2007, 18h08
  4. [PHP-JS] Variable PHP comme argument dans l'appel d'une fonction Javascript
    Par The Molo dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 26/04/2007, 09h00
  5. pb dans l'appel d'une fonction
    Par badboys206s16 dans le forum ASP
    Réponses: 3
    Dernier message: 04/07/2006, 08h32

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