void f(int val) vs void f(int & val) - C++ - Programmation
Marsh Posté le 05-11-2009 à 06:54:02
par référence ou par référence constante. La ton exemple est foireux car la sémantique de la fonction change.
Marsh Posté le 05-11-2009 à 07:40:37
disons les deux cas, par rapport à un passage par référence et par rapport à un passage par référence constante
Marsh Posté le 05-11-2009 à 12:54:01
Si ce que tu veux comme cas d'utilisation, c'est du void f(int val), le passage par valeur sera plus économique.
Maintenant je dirais (probablement mal):
A partir du moment où tu as une référence, la logique voudrait que le compilo déréférence la référence a chaque utilisation car l'objet référencé peut avoir changé (bon à voir peut être avec volatile).
void f(int val)
{
while (val)
{
poulpe();
--val;
}
}
void f(int &val)
{
while (val)
{
poulpe(); // poulpe peut avoir changé le int
--val;
}
}
Maintenant je sais pas si c'est une remarque à la con. (et que le compilo n'optimisera pas que si y'a un volatile en plus )
edit: je me suis pris les pieds dans le tapis en voulant faire une démo foireuse >> seek coffee.
Mais si tu cherche les perfs, à partir du moment où le type rentre dans un registre du cpu (ou plusieurs de manière efficace) c'est int ou const int (le const permettant entre autre au niveau optimisation de garantir que l'appelé ne modifia pas le registre utilisé pour le passage).
Enfin je dis ça comme ça moa.
Marsh Posté le 05-11-2009 à 13:18:14
ReplyMarsh Posté le 05-11-2009 à 15:24:53
Joel F a écrit : gcc à l'air de pas tenir compte des const& sur les types atomiques. |
Il donne pourtant le resultat que j'attends pour
Code :
|
Marsh Posté le 05-11-2009 à 16:09:29
il voulait dire const int & nope ?
oupa ?
ha non café
Marsh Posté le 05-11-2009 à 17:45:38
Un Programmeur a écrit : |
je veut dire que le code généré pour f(int) et f(int cosnt& ) est identique ...
Marsh Posté le 05-11-2009 à 19:28:14
C'est bien ce que j'avais compris. Je vois mal comment c'est possible si on veut traiter correctement le genre de cas que j'ai donné (hormis si f est statique et qu'on ne passe jamais de pointeurs à f à une fonction dont on ne voit pas le code et tous les appels...).
Marsh Posté le 05-11-2009 à 19:43:16
Un Programmeur a écrit : C'est bien ce que j'avais compris. Je vois mal comment c'est possible si on veut traiter correctement le genre de cas que j'ai donné (hormis si f est statique et qu'on ne passe jamais de pointeurs à f à une fonction dont on ne voit pas le code et tous les appels...). |
Hmmmm, soit y a inference de l'origine de la référence soit ca a changé.
Je comprends pas pourquoi j'ai le résultat p=0,p=42 d'ailleurs au vu du code.
Marsh Posté le 05-11-2009 à 19:50:49
C'est pourtant le comportement attendu. Une référence est un alias pour l'objet initial (ici i), le fait qu'on ne puisse pas modifier l'objet en utilisant cet alias n'empêche pas de pouvoir le faire en utilisant un autre accès.
Et si tu parles du code généré, ça me semble compréhensible ici -- g++ 4.2 sur x86. En gros c'est compilé comme
Code :
|
Marsh Posté le 05-11-2009 à 20:12:43
Et bien?
Appel de f dans main:
Code :
|
on passe l'adresse de i. Code de f
Code :
|
On voit bien qu'on déréférence ce qui est passé (DWORD PTR[%edi]).
(g++ -O2 -masm=intel -S puis le résultat est passé dans c++filt pour démangler les noms)
Marsh Posté le 05-11-2009 à 20:22:38
je viens de vérifier. Je m'a fait eu comme une tanche donc.
Marsh Posté le 05-11-2009 à 21:06:21
bon in finé c'est quoi le verdict en terme de perf :$
Marsh Posté le 05-11-2009 à 21:22:14
J'ai du mal à comprendre pourquoi tu veux comparer par valeur et par référence non constante, le choix entre les deux doit se faire à mon avis sur des considérations sémantiques.
Entre par valeur et par référence constante et si on a le choix -- autrement dit, si les considérations de possibilité d'alias n'impose pas l'un ou l'autre -- par valeur devrait généralement être plus performant (mais comme toujours 1/ est-ce que ce n'est pas prématuré d'envisager ce genre de chose 2/ mesure 3/ est-ce que le gain vaut la peine)
Marsh Posté le 05-11-2009 à 21:23:44
et surtout paye ta micro-optimisation qui sert à rien 99% du temps
Marsh Posté le 05-11-2009 à 21:32:58
pour mesurer sous visual, vous utilisez quoi typiquement ? je me heurte à ce problème , QueryCouter & co ? et si oui de quelle manière le faite vous
Marsh Posté le 05-11-2009 à 22:40:59
Tu veux mesurer quoi ? Une différence entre passage par référence et passage par valeur ?
Marsh Posté le 06-11-2009 à 00:57:05
Tu va mesurer du bruit
Quand c'est une implémentation d'un algo avec une charge de travail réaliste, les queryperfcounters & autres sont corrects.
Mais pour ce genre de trucs faudrait du rdtsc.
Dans tous les cas c'est de l'enculage de mouche, d'autant plus que la donne peut changer si le compilo peut faire de l'inlining sauvage ou de la compilation lors de l'édition des liens, ou pas (link dll/lib statique).
Comme dit plus haut, le code tu le fais de la manière la plus élégante possible et la plus cohérente avec l'intention initiale, et autrement pour un type qui tiens dans un ou deux registre => valeur, classe/struct => ref.
Marsh Posté le 07-11-2009 à 14:59:01
ok ok donc au final ça revient au même alors
Marsh Posté le 08-11-2009 à 10:24:39
A lire avant de chercher a optimiser http://www.linux-kongress.org/2009 [...] eitner.pdf
Marsh Posté le 04-11-2009 à 23:20:38
salut,
en terme de perf le fait de passer des types de base par référence est-il plus lent que de les passer par valeur ou cela revient il exactement au même ?
merci
---------------
.