OVH Cloud OVH Cloud

vitesse: if vs pointeur de methode

126 réponses
Avatar
Guillaume Desticourt
bonsoir,

je m interroge sur la vitesse d execution entre une comparaison et un
pointeur de methode.
j ai une class dont une methode peut changer de comportement au cours de
la vie du process, mais cela rarement.
je me demandais si je devais avoir une methode unique avec un bloc
if/else ou alors un pointeur de methode sette a la methode qui va bien.
j ai donc ecrit deux petits programmes de test, et la solution if/else
est /visiblement/ plus rapide.
et donc je me demandais:
- est ce que mon test est pertinent?
- pourquoi une telle difference de temps?

les prog ont ete compile sous un linux 2.6 avec g++ 3.3.5

merci,

def.hh
------


#ifndef DEF_HH
# define DEF_HH

#include <stdlib.h>

#define MAX_LOOP 1000000000

class Test;

typedef int (Test::*behavior_t)(void);

class Test
{
public:
Test() :
_test(true)
{
}

int behavior1(void)
{
return 0;
}
int behavior2()
{
return 0;
}

inline bool isTrue(void)
{
return _test;
}
private:
bool _test;
};

#endif

if.cc
-----


#include "def.hh"

int main(void)
{
Test * test = new Test();

for (unsigned long u = 0;
u < MAX_LOOP;
++u)
{
if (test->isTrue())
test->behavior1();
else
abort();
}
return 0;
}


pointer.cc
----------



#include "def.hh"

int main(void)
{
Test * test = new Test();
behavior_t behavior;
if (test->isTrue())
behavior = &Test::behavior1;
else
abort();

(test->*behavior)();


for (unsigned long u = 0;
u < MAX_LOOP;
++u)
{
(test->*behavior)();
}
return 0;
}


Makefile
--------

all: iftest pointertest

iftest: def.hh
g++ -Wall -Werror -O2 if.cc -o iftest

pointertest: def.hh
g++ -Wall -Werror -O2 pointer.cc -o pointertest

clean:
rm -f *.o
rm -f *~
rm -f iftest pointertest


une tarball est - provisoirement - disponible ici:
http://www.freenopen.net/~guillaume/info/prog/source/ifpointerbench-20050720-1755.tar.bz2

--
Guillaume Desticourt

10 réponses

Avatar
Fabien LE LEZ
On Fri, 22 Jul 2005 00:55:33 +0200, Guillaume Desticourt
:

Juste pour info, l'implementation fait probablement elle-meme un test
sur le pointeur pour savoir s'il sagit d'un pointeur de fonction membre
ou de methode.


quelle difference fais tu entre entre une fonction membre et une
methode?? je croyais que cela designait la meme chose...


Bonne question. Le mot "méthode" est rarement employé sur
fr.comp.lang.c++ parce qu'on ne sait jamais trop ce qu'il veut dire.
S'il y a effectivement une différence entre "méthode" et "fonction
membre", je suppose que ça veut dire que "méthode" est compris ici
comme "fonction membre virtuelle".


Avatar
Michel Michaud
Dans le message 42e009b7$0$23954$,
Michel Michaud wrote:

D'ailleurs, je n'ai pas dit « fait », j'ai dit « fera » (ou plutôt
« vont faire ». Ceux qui feront du C++/CLI feront du vrai C++/CLI,
ce sera la chose normale, courante, standard quoi (oups !). Pour le
moment personne ne peut vraiment faire du C++/CLI...


Encore que. S'il y a plusieurs implémentation de C++/CLI (ce qui est
loin d'être impossible, voir go-nomo), n'y a-t-il pas des chances
que, comme pour C++, l'interprétation ou le respect de la norme
varie avec l'implémentation choisie ? Du coup, ne risque-t-on pas
de se retrouver dans une situation similaire à celle de C++ ?


Pour la non conformité, je suppose que oui, principalement à cause
des bogues, mais même si le compilateur EDG ou Comeau a des bogues,
ceux qui les utilisent ont au moins l'impression d'avoir ISO C++ à
leur disposition :-) Il reste que la bibliothèque de C++/CLI (la
charpente .NET complète en fait) est plus vaste et assez complète,
un peu comme en Java. Et c'est là qu'au quotidien, on peut voir la
différence la plus importante je crois...

--
Michel Michaud
http://www.gdzid.com
FAQ de fr.comp.lang.c++ :
http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ/


Avatar
Michel Michaud
Dans le message ,
Bonne question. Le mot "méthode" est rarement employé sur
fr.comp.lang.c++ parce qu'on ne sait jamais trop ce qu'il veut dire.
S'il y a effectivement une différence entre "méthode" et "fonction
membre", je suppose que ça veut dire que "méthode" est compris ici
comme "fonction membre virtuelle".


J'ai aussi remarqué que pour ceux qui commencent par C++, ou par
des langages non objets, le mot méthode ressemble à un jargon
inutile, inventé seulement pour leur donner l'idée qu'il se passe
quelque chose de bien différent.

«
- Mais monsieur prof de C#/Java, c'est quoi une méthode ?
- C'est une fonction décrite dans la classe. Donc une fonction
qui est un membre de la classe.
- Ah ! Juste ça ? Il y a surement autre chose de particulier ?
- Non.
- Eh ben... On devrait les appeler « fonction membre », tout
simplement non ?
- Ah non, ça c'est autre chose...
- Quoi ?
- C'est une fonction décrite dans la classe. Donc une fonction
qui est un membre de la classe. Mais ça n'existe qu'en C++.
- Je vois !*!?**!!!???
»

Quelqu'un a-t-il déjà vu une explication du principe des
« méthodes » où ce terme semble justifié adéquatement ?

--
Michel Michaud
http://www.gdzid.com
FAQ de fr.comp.lang.c++ :
http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ/

Avatar
Gabriel Dos Reis
"Michel Michaud" writes:

[...]

| Quelqu'un a-t-il déjà vu une explication du principe des
| « méthodes » où ce terme semble justifié adéquatement ?

Si un gugus s'amène sur ce forum et s'entête à ne converser
exclusivement qu'en Anglais (tout en sachant parler Français et le
status de ce forum), tu trouverais cela un brin déplacé, non ?

-- Gaby
Avatar
kanze
Richard Delorme wrote:


Le C++ a deux gros avantages :

- c'est un langage très puissant, très riche ;


Je ne trouve pas justement. Des langages comme Java, Python,
Ruby, etc dont beaucoup plus riches et supportent plein de
fonctionnalité nativement (multi-threads, graphismes,
réseau, ramasse-miette, etc.)


AMHA, tu confonds richesse du langage et richesse de la/les
bilbiothèque(s)fournie()s avec le langage : Il est vrai que
les bilbiothèques standards de ces langages couvrent un
spectre de besoins plus large que ce qui est couvert par le
C++,


Séparer ce qui est du ressort de la bibliothèque et du langage
est difficile. Par exemple, synchronized est un mot clé de
Java, sert au multi-tâche, et ne fait pas partie d'une
bibliothèque. On peut dire la même chose des ramasses-miettes,
c'est une propriété de ces langages et non une bibliothèque.
En Python, "print" est une instruction et non une fonction
d'une bibliothèque. Même en C++, une notion comme la chaine de
caractère est partagée par le langage (avec les chaines
littérales) et la bibliothèque (std::basic_string, les
fonctions str*(), etc.).


Il y a effectivement différents degrées de séparation. J'ai déjà
travaillé sur des processeurs où l'opérateur /, sur un entier,
était une fonction. N'empêche qu'il s'agit bien des degrées :
dans le cas du multithreading ou du glanage des cellules, une
certaine integration dans le langage s'impose, exactement comme
dans le cas de std::type_info. À l'autre extrème, même si c'est
formalement normalisé comme partie du langage, je crois qu'on
peut bien regarder quelque chose comme Java Swing comme une
bibliothèque à part, séparée du « langage » en tant que tel.

En ce qui doit supporter la norme, la tradition en C++ vient en
partie de C, est assez complexe. J'avoue qu'il me semble assez
difficile de justifier la présence des fonctions comme reverse
ou random_shuffle, ou l'absence du support pour les sockets.
Sauf en prenant en compte l'histoire du langage et des
bibliothèques.

--
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




Avatar
kanze
Richard Delorme wrote:
En revanche, le langage fait un
maximum pour rendre le développement des gros projets
difficiles,


La plupart des critiques que je lis sur Java et les gros projets
ressemble à celle là :
http://www.disordered.org/Java-QA.html#Java-8

C'est-à-dire :
-le langage, en lui-même, est bien pour les gros projets
(objets, modularité, etc.).
-les grosses applications en Java marchent mal (démarrage
lent, grosse consommation de ressource, etc.), ce qui pour moi
est un problème de performances.

Quels sont les autres reproches à faire à Java pour le
développement de gros projets ?


D'abord, il faut évidemment rélativiser : avec un processus
adéquat, on peut tout faire, ou prèsque, et on a bien réalisé
des gros projets avec des langages encore moins convenant que
Java. Mes propos s'adressent surtout dans la contexte Java vs.
C++ (ou Java convient bien moins que C++ pour de gros projets).

Le plus gros problème, évidemment, c'est qu'il melange
implémentation et interface (au sens général, et non au sens du
mot clé Java). Le langage même (et non seulement les
implémentations actuelles) exige que je mets tous les détails de
l'implémentation dans le même fichier physique que la
spécification de l'interface, et même que je les melange à
l'intérieur du fichier -- je ne peux pas, par exemple, mettre
la spécification en tête du fichier, et l'implémentation à la
suite. Alors que dans tous les gros projets où j'ai travaillé en
C++, il fallait davantage d'autorité pour modifier un en-tête
(dont dépendent les autres) qu'un fichier source.

En principe, je crois que les solutions serait possibles (donc,
par exemple, deux types de check-out, dont un qui réfuse un
check-in si l'interface publique a été modifiée), mais il faut
dire qu'elles ne sont pas présentes dans les outils existants.
Qui bien trop souvent semblent prendre l'attitude que le
programmeur de l'instant est roi, et qu'il a droit à faire tout
ce qu'il veut, même si ça casse tout le code client de sa
classe. Alors qu'une bonne gestion des interfaces entre les
composants est essentielle dans un grand projet.

Note bien que la solution de C++ est loin d'être idéal non plus.
Mais c'est une faiblesse reconnue (au moins de certains), et le
comité essaie (et a essayé) de s'y adresser (« export » des
templates, par exemple, et aujourd'hui, la considération des
« modules ») -- je connais peu de personnes qui considère que
l'inclusion textuelle soit *la* solution au problème.

Pour la reste, j'ai des assez bonnes expériences avec la
programmation par contrat dans de grands projets. Ici, le C++
n'a pas de supporte direct, mais il s'est développé des idiomes
(avec des fonctions virtuelles privées) pour l'implémenter,
quand elle convient. Ici, le langage de Java rend la
programmation par contrat même impossible, ou au moins, beaucoup
plus difficile : il faut se limiter à l'héritage simple, avec
beaucoup de classes supplémentaires intermédiaires. De même, je
préfère les erreurs le plus tôt possible -- l'absense des
templates et le fait que tout dérive d'Object pose un problème
ici (mais je crois que ce problème est reconnu même par ceux qui
font le Java, et que des versions les plus récentes de Java ont
des templates).

[...]

Le raisonnement va assez loin : si tu as quelques Mo de
données, tu peux les charger entièrement en mémoire, dans
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^



tes propres structures, plutôt que d'utiliser un moteur
externe de base de données


Ce n'est pas un exemple d'optimisation ça ?


Optimisation de quoi ? Côté vitesse d'exécution, c'est
prèsque sûrement une pessimisation, à moins que tu te sens
capable tout seul d'optimiser les accès mieux que Oracle
(qui y met des moyens).


Tout charger en mémoire est à coup sûr une forme
d'optimisation. Le temps d'accès à la mémoire se mesure en
nanosecondes, au disque en microsecondes. Même sans être un
génie de la programmation, on part avec un gros avantage, là.


Les bases de données (comme Oracle) garde une bonne partie des
données en mémoire aussi. Et charger toute la base en mémoire
pour deux ou trois accès n'est pas forcément une optimisation
non plus.

Évidemment, tout dépend de l'application. Les critères pour un
serveur, qui démarre quand la machine est booté, et qui traite
des millions de requêtes sans qu'on reboote la machine, sont
différents de ceux d'un programme client invoquait à la ligne de
commande, pour une seule requête. Et les critères de recherche
entre aussi en ligne de jeux : si c'est toujours sur une seule
et même indice, sur l'égalité d'indice, ce n'est pas la même
chose que si tu fais des jointures sur plusieurs tables, avec
des critères de recherche plus ou moins arbitraires qui
associent des champs de divers types d'objets. Mais en général,
dès que les critères d'accès cessent d'être triviaux, on a tout
intérêt à prendre une véritable base de données, plutôt que
d'essayer d'écrire le code soi-même. Surtout pour l'efficacité
des programmeurs, mais aussi, si les critères sont réelement
complexes, pour l'efficacité en termes de temps d'exécution.

--
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




Avatar
Laurent Deniau
Fabien LE LEZ wrote:
On Fri, 22 Jul 2005 00:55:33 +0200, Guillaume Desticourt
:


Juste pour info, l'implementation fait probablement elle-meme un test
sur le pointeur pour savoir s'il sagit d'un pointeur de fonction membre
ou de methode.



quelle difference fais tu entre entre une fonction membre et une
methode?? je croyais que cela designait la meme chose...



Bonne question. Le mot "méthode" est rarement employé sur
fr.comp.lang.c++ parce qu'on ne sait jamais trop ce qu'il veut dire.
S'il y a effectivement une différence entre "méthode" et "fonction
membre", je suppose que ça veut dire que "méthode" est compris ici
comme "fonction membre virtuelle".


Yep. Cf TC++PL3 sur les fonctions membres virtuelles. J'ai utilise
methode par simple flemme de tout retaper et fmv c'est plus obscurs ;-)

a+, ld.



Avatar
kanze
Fabien LE LEZ wrote:
On Thu, 21 Jul 2005 09:17:18 -0400, "Michel Michaud" :

si tu as quelques Mo de données, tu
peux les charger entièrement en mémoire, dans tes propres
^^^^^^^^^^^^^^^^^^^


Je vois mal comment on peut s'assurer de ça dans les systèmes
d'exploitation modernes...


J'ai bien dit "en mémoire", pas "en RAM physique".

Du point de vue du programmeur C++, il n'y a pas de différence
entre la RAM physique et la mémoire virtuelle.


Du point de vue du langage, non. Le langage ignore les questions
de vitesse. Du point de vue du programmeur, en revanche, il faut
bien en tenir compte, au moins dans les cas limites.

Et en pratique, sous Windows au moins, si tu as une petite
quantité de données (mettons, 10 ou 20 Mo), ça n'augmentera
pas sensiblement le phénomène de swapping.


En pratique, si toutes les données de tous les programmes qui
tournent sur la machine tiennent en mémoire physique, il n'y a
pas de problème de swapping (au moins sous Solaris, où je l'ai
bien expérimenté, mais j'imagine que Windows, c'est pareil). Dès
qu'un des programmes commencent à dépasser un peu, tout le monde
rallentit -- j'ai une machine avec assez peu de mémoire, et dès
que je fais une édition de liens (l'éditeur de liens de Solaris
est très gourmand en mémoire), Netscape, emacs et vim deviennent
pour ainsi dire inutilisable.

Alors, tout dépend de l'application. Moi, j'écris surtout des
serveurs, qui tournent sur des machines dédiées. Dans la
programmation, on utilise la mémoire qu'il faut, sans trop
s'inquiéter. Parce que la machine sur laquelle il tourne va
avoir toute la mémoire qu'il faut, et il n'aurait pas d'autre
application qui tourne dessus. Pour une application qui doit
tourner sous Windows, parmi d'autres applications, les
considérations sont différentes.

--
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



Avatar
kanze
Fabien LE LEZ wrote:
On 21 Jul 2005 17:24:38 +0200, Gabriel Dos Reis
:

En ce qui concerne ta question, je pourrais te dire que MS
est une très *grande* entreprise et donc emploie des gens
avec des vues assez diversifiées :-).


D'autant que C# concerne principalement le service marketing.
Les gus qui font tout à fait autre chose (développement de
Office par exemple) n'ont rien à voir là-dedans.


Au moins qu'on lui impose C# d'en haut. Ou simplement que MS se
désintéresse de C++ au point à laisser moribonder le compilateur
(comme fait Sun) ; je doute que les gus qui développe Office ait
le droit d'utiliser g++.

Mais ce ne sont que des scénarios possibles. Pour l'instant,
tout ce que je vois actuellement me fait croire que MS considère
encore C++ un langage de l'avenir. Non le seul langage, mais un
des langages.

--
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


Avatar
kanze
Arnaud Meurgues wrote:
wrote:

créer du code réelement robuste. Et je n'ai pas encore
régardé du côté C# ; puisque je travaille sous Solaris, ce
n'est même pas une option.


Mais si : http://www.mono-project.com/Mono:SPARC


Il y a des options théoriques, et il y a des options réeles. (À
vrai dire, je n'arrive pas toujours à comprendre ce qui en fait
la différence, mais les chefs, eux, prétendent le comprendre.)

--
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