Pourquoi la surchage a-t-elle si mauvaise réputation ?

Pourquoi la surchage a-t-elle si mauvaise réputation ? - C++ - Programmation

Marsh Posté le 10-10-2004 à 01:43:57    

Bonsoir bonsoir.
 
Bin alors je lis partout: le C++ peut être quasi aussi rapide que du C si on évite la ligature dynamique, telle lib dit: on a pas utilisé l'héritage virtuel pour éviter la chute de perfs, etc...
Alors moi je me suis posé la question: pourquoi c'est réputé si lent ?
Test:
 

Code :
  1. class Parent
  2. {
  3. public:
  4. virtual int getValue(int a) { return a+a; }
  5. virtual int getSecondValue(int a) { return 2*a-a; }
  6. };
  7. class Fils : public Parent
  8. {
  9. public:
  10. virtual int getValue(int a) { return a*a; }
  11. virtual int getSecondValue(int a) { return 4*a-a; }
  12. };
  13. int main()
  14. {
  15. Parent* p;
  16. Fils f;
  17. p = &f;
  18. p->getValue(3);
  19. p->getSecondValue(3);
  20. }


 
(je sais y'a pas de return dans main mais c pas la question)
Après compilation avec les 4 virtual, sous vc7.1 en mode debug sans optimisations, on obtient pour main:
 

Code :
  1. _main PROC NEAR
  2. ; 16   : {
  3. push ebp
  4. mov ebp, esp
  5. sub esp, 8
  6. ; 17   :  Parent* p;
  7. ; 18   :  Fils f;
  8. lea ecx, DWORD PTR _f$[ebp]
  9. call ??0Fils@@QAE@XZ
  10. ; 19   :  p = &f;
  11. lea eax, DWORD PTR _f$[ebp]
  12. mov DWORD PTR _p$[ebp], eax
  13. ; 20   :  p->getValue(3);
  14. push 3
  15. mov ecx, DWORD PTR _p$[ebp]
  16. mov edx, DWORD PTR [ecx]
  17. mov ecx, DWORD PTR _p$[ebp]
  18. call DWORD PTR [edx]
  19. ; 21   :  p->getSecondValue(3);
  20. push 3
  21. mov eax, DWORD PTR _p$[ebp]
  22. mov edx, DWORD PTR [eax]
  23. mov ecx, DWORD PTR _p$[ebp]
  24. call DWORD PTR [edx+4]
  25. ; 22   : }
  26. xor eax, eax
  27. mov esp, ebp
  28. pop ebp
  29. ret 0
  30. _main ENDP


 
En virant les 4 virtual:
 

Code :
  1. _main PROC NEAR
  2. ; 16   : {
  3. push ebp
  4. mov ebp, esp
  5. sub esp, 8
  6. ; 17   :  Parent* p;
  7. ; 18   :  Fils f;
  8. ; 19   :  p = &f;
  9. lea eax, DWORD PTR _f$[ebp]
  10. mov DWORD PTR _p$[ebp], eax
  11. ; 20   :  p->getValue(3);
  12. push 3
  13. mov ecx, DWORD PTR _p$[ebp]
  14. call ?getValue@Parent@@QAEHH@Z  ; Parent::getValue
  15. ; 21   :  p->getSecondValue(3);
  16. push 3
  17. mov ecx, DWORD PTR _p$[ebp]
  18. call ?getSecondValue@Parent@@QAEHH@Z  ; Parent::getSecondValue
  19. ; 22   : }
  20. xor eax, eax
  21. mov esp, ebp
  22. pop ebp
  23. ret 0
  24. _main ENDP


 
Moi les différences que je vois sont:
 - appel d'un constructeur de Fils, qui appelle un constructeur de Parent en virtual, ce qui n'est pas fait en non virtual. Vlà le code du constructeur de Fils au cas où on me le demande:

Code :
  1. ??0Fils@@QAE@XZ PROC NEAR    ; Fils::Fils, COMDAT
  2. ; _this$ = ecx
  3. push ebp
  4. mov ebp, esp
  5. push ecx
  6. mov DWORD PTR _this$[ebp], ecx
  7. mov ecx, DWORD PTR _this$[ebp]
  8. call ??0Parent@@QAE@XZ
  9. mov eax, DWORD PTR _this$[ebp]
  10. mov DWORD PTR [eax], OFFSET FLAT:??_7Fils@@6B@
  11. mov eax, DWORD PTR _this$[ebp]
  12. mov esp, ebp
  13. pop ebp
  14. ret 0
  15. ??0Fils@@QAE@XZ ENDP     ; Fils::Fils


 
 - un appel des fonctions via un offset depuis this, et une écriture d'ecx 2 fois pareil... donc une inutile.
 
Soit au coût de l'appel, 2 mov en plus et un call indirect, ce qui devrait pas faire plus de 3-4 cycles en plus par appel, ce que je trouve super négligeable comparé au temps d'exécution d'une fonction normalement longue/complexe... Je vois pas trop la différence avec utiliser un pointeur de fonction en C, qui serait le moyen que j'utiliserais normalement pour remplacer ces virtual.
 
Quelqu'un peut m'expliquer pourquoi on dit que c'est lent alors ?
Merci !

Reply

Marsh Posté le 10-10-2004 à 01:43:57   

Reply

Marsh Posté le 10-10-2004 à 01:59:21    

ben y a que les cons qui disent ça. Y a toujours des cons pour pas comprendre. Les gens familiers du C++ comprennent bien que la virtualité implique un traitement supplémentaire. Mais y aura toujours des abrutis qui font de la branlette intellectuelle.
 
 
Cela dit : si tu vires les virtual, magique, le compilateur génère un return 0 est rien d'autres :D

Reply

Marsh Posté le 10-10-2004 à 09:38:11    

Taz a écrit :

ben y a que les cons qui disent ça. Y a toujours des cons pour pas comprendre. Les gens familiers du C++ comprennent bien que la virtualité implique un traitement supplémentaire. Mais y aura toujours des abrutis qui font de la branlette intellectuelle.


 
Ces cons la si on les ecoutés, faudriat faire du C avec des cout et basta :|
 
le virtual comme le template c'ets bien quand on en sert correctement point.
 
Les onanistes du bulbe sont peut-etre juste un gros tas de mauvais codeur.

Reply

Marsh Posté le 10-10-2004 à 09:43:47    

Citation :

Ces cons la si on les ecoutés, faudriat faire du C avec des cout et basta :|


les cout c'est pas du C :/


---------------
I mean, true, a cancer will probably destroy its host organism. But what about the cells whose mutations allow them to think outside the box by throwing away the limits imposed by overbearing genetic regulations? Isn't that a good thing?
Reply

Marsh Posté le 10-10-2004 à 10:31:26    

Masklinn a écrit :

Citation :

Ces cons la si on les ecoutés, faudriat faire du C avec des cout et basta :|


les cout c'est pas du C :/


 
il veut dire que ces cons en question font du c avec des cout en guise de c++

Reply

Marsh Posté le 10-10-2004 à 11:03:19    

cris56 a écrit :

il veut dire que ces cons en question font du c avec des cout en guise de c++


Ah oui, du C++ avec des malloc quoi :love:


---------------
I mean, true, a cancer will probably destroy its host organism. But what about the cells whose mutations allow them to think outside the box by throwing away the limits imposed by overbearing genetic regulations? Isn't that a good thing?
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed