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

Arnaud

Avatar
Richard Delorme
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 ?

[...]

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


--
Richard



Avatar
Matthieu Moy
Richard Delorme writes:

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


Si tu as besoin de toutes les données et si tu es certain que tout
tiendra en RAM, c'est vrai.

Mais il y a deux conditions qui sont loin d'être satisfaites tout le
temps. Quand tu as besoin d'accéder à un enregistrement d'une base de
données, tu es bien content de pouvoir ne charger que le bout qui te
sert. Tout charger en mémoire est un gaspillage énorme. Et même quand
tu as besoin de toutes les données, quand elles sont trop importantes,
il vaut mieux ne garder que la "fenêtre" courrante en mémoire et le
reste sur le disque. Les logiciels de retouche d'image ont en général
un système comme ça pour pouvoir ouvrir les gros bitmaps (essaye
d'ouvrir une image de 20 000 x 20 000 ou plus dans un logiciel de
dessin bas de gamme pour voir).

--
Matthieu

Avatar
Guillaume Desticourt
wrote:
Guillaume Desticourt wrote:

[...]


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.



La solution classique ici, c'est la modèle stratégie, non ?


d'apres ce que je lis dans Design Patterns, Catalogue de modeles de
conception reutilisables de Gamma Helm Johnson et vissides, la strategy
sert a remplacer:

switch(_srategie):
case STRATEGY1
behavior1();
break;
case STRATEGY2:
behavior2()
...

par:

_strategie->behavior();

donc oui ca a l air de coller, mais:
vu que je dois pouvoir changer de comportement, il faudrait que
_compositeur soit un pointer sur la strategie qui m interesse, donc dans
ma classe j aurais un set de disons 2 strategies differentes, et
_strategie serait settee sur un element de mon set, puis change sur l
autre etc...
j aurais donc
- un Strategy * pointant sur un des...
- deux Strategy * (un &Strategy1 et un &Strategy2)

bon ca revient au meme que mon pointer de methode si ce n est que au
lieu de bosser avec des objets Stratetegy ma solution de pointer de
methode bosser avec des methodes behavior, et que le behavior est donc
dans ma classe principale au lieu d etre dans une derivee de Strategy.
bref il me semble que c est pareil?

Est-ce qu'il y a des raisons pour faire autre chose ? D'après
mon expérience :

-- La syntaxe de l'utilisation des pointeurs deplaît à
beaucoup. Moi, je m'en sers de temps en temps, mais chaque
fois, j'ai dû bien en justifier l'utilisation dans les
révues de code. Il faut donc bien une justification pour les
utiliser.

-- L'utilisation des if/else (dans ce cas-ci) risque de donner
des fonctions trop grandes et trop complexes.



d'accord mais dans ce cas, et apres reflexion suite a ce thread, je me
demande si ce n est pas la meilleure solution, en effet le code du if et
du else sont quasi identique, a 4 lignes pres, ainsi, dispatcher le
code dans des fonctions differentes n est peut etre pas pertient
notamment au niveau de la maintenance du code.

en esperant avoir ete clair,
cordialement,

--
Guillaume Desticourt


Avatar
Michel Michaud
Dans le message ,

- l'exécution des programmes est généralement rapide, ce qui
permet souvent de ne pas se préoccuper d'optimisation. 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
^^^^^^^^^^^^^^^^^^^


Je vois mal comment on peut s'assurer de ça dans les systèmes
d'exploitation modernes... Et si le va-et-vient commence (swapping
en anglais, pour ceux qui veulent suivre :-) et que ça finit en
thrashing (je ne me souviens plus du mot français cette fois !), ce
sera le contraire de l'optimisation que tu auras réussi.

structures, plutôt que d'utiliser un moteur externe de base de
données, avec tous les problèmes de déploiement que ça implique.


Alors l'idéal sera de faire un logiciel qui intègre sa propre
gestion de données « à la » BD :-)

--
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 ,
On 21 Jul 2005 00:26:43 -0700, :

Et je n'ai pas encore régardé du côté C#


A priori, C# a un gros inconvénient par rapport à C++ : la
pérennité. Ça m'étonnerait beaucoup que Microsoft ne décide pas,
dans quelques années, que C# c'est dépassé et qu'il faut
l'abandonner.


Ouais... comme COBOL... Comme C++... :-)

(En fait, on peut dire que MS a laissé tomber C++ car pour
programmer sous .NET, la nouvelle plate-forme, C++ ne suffit
plus, il faut Managed C++ (mort) ou C++/CLI).

Plus sérieusement : s'il y a une meilleure alternative, ce sont
les développeurs qui vont laisser tomber C# avant MS. Pour le
moment, C++/CLI s'annonce bien, mais on verra si les gens qui
ont appris C# voudront avoir « plus »...

--
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 ,
Fabien LE LEZ wrote:
A priori, C# a un gros inconvénient par rapport à C++ : la
pérennité. Ça m'étonnerait beaucoup que Microsoft ne décide
pas, dans quelques années, que C# c'est dépassé et qu'il faut
l'abandonner.


Comme ils ont fait avec Visual Basic ? (Je me suis laissé dire
qu'il n'y a que le nom qui n'a pas changé.)


Ce n'est pas un changement pire que le passage de ISO-C++ à
C++ pour .NET dans toutes ses formes (Managed C++ ou C++/CLI).

Remarque, des mauvaises langues pourraient dire la même chose du
C++. Le C++ que j'utilise aujourd'hui n'a que peu de choses en
commun avec le C++ que j'ai appris il y a vingt ans. (J'exagère
beaucoup, évidemment. N'empêche que prèsque rien que j'ai écrit
il y a 20 ans tournerait aujourd'hui sans modification.)


C'est ce que j'allais dire : même sans les dérivations de C++
vers .NET ou autres, C++ a acquis tellement de choses avec les
templates qu'il a changé plus que tout autre langage je crois.
Et je pense que la prochaine version standardisée amènera aussi
plusieurs modifications importantes (je considère qu'elles sont
importantes, même quand le code qu'on a écrit continue à
fonctionner, s'il devient tout d'un coup « mal écrit » selon les
nouvelles façons de faire qui sont possibles).

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

| Dans le message 42df6653$0$2521$,
| >> Y'a quand même une grosse différence: C# est standardisé (ISO et
| >> ECMA si mes souvenirs sont bons). Il y en a plusieurs
| >> implémentations.
| >
| > Comme le managed C++... Euh, je veux dire le C++/CLI... ;)
|
| Non, Managed C++ n'a pas été standardisé. C++/CLI le sera et je
| crois qu'il sera alors plus « standard » que C++ lui-même ! Il

Cela veut dire quoi exactement ?

-- Gaby
Avatar
Gabriel Dos Reis
"Michel Michaud" writes:

| (En fait, on peut dire que MS a laissé tomber C++ car pour

C'est intéressant, parce que selon des sources sûres, MS encourage
les dévelopements internes en C++, et non plus en C# comme cela a été
la politique juste après le lancement de la propagande C#.

-- Gaby
Avatar
Michel Michaud
Dans le message ,
"Michel Michaud" writes:
Non, Managed C++ n'a pas été standardisé. C++/CLI le sera et je
crois qu'il sera alors plus « standard » que C++ lui-même ! Il


Cela veut dire quoi exactement ?


Je te dirais que j'expliquais un peu dans la portion que tu as
coupée, mais je suppose que tu n'as pas compris exactement ce
que je voulais dire... J'étais peut-être un peu trop subtil avec
mon mot standard entre guillemets :-(

C'est sûr qu'un standard officiel est un standard officiel, mais
je prenais le mot standard dans son sens général de courant,
habituel, etc¹. Ceux qui vont faire du C++/CLI ne pourront faire
que ça (tout ce qu'ils auront besoin sera là), alors que ceux qui
font du C++ ne peuvent le plus souvent ni s'y limiter (il faut
des bibliothèques ou des garanties supplémentaires), ni l'utiliser
complètement (par manque de conformité des compilateurs courants).

¹ Plusieurs personnes ont reproché au comité d'avoir innové en
standardisant C++ au lieu de confirmer la pratique courante. Je
ne suis personnellement pas de ceux-là et j'espère que la
prochaine version de C++ sera encore « meilleure »... mais je ne
suis pas un développeur comme tel !

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