Return std::string("blabla");

Je suis en train de me demander si ce genre de choses est une bonne idée niveau performances…

std::string f() { std::string text("coucou"); return text; }

Va-t-il y avoir copie de la chaîne ? Ou le compilo est-il généralement assez futé que pour bien optimiser ça ? Je sais ce que vous allez me dire : “sors-toi les doigts du fion, compile ton code, lance en debug et lis l’assembleur”, mais ça risque de me prendre un temps dingue, vu mes connaissances assez légères en asm x86.

Et surtout, imaginez une longue succesion d’appels du genre :

[code]std::string g() {
return f();
}

std::string h() {
return g();
}[/code]

Si il y a copie à chaque fois, ça va finir par faire lourd. Alors, quid ?

edit : bien sûr, dans mon exemple “coucou” est tout ce qu’il y a de plus statique, y’a moyen de faire ça bien plus intelligemment… Le cas qui m’intéresse, c’est celui où la chaîne renvoyée peut être différente pour chaque instance de la classe.

Et aussi, pensez-vous qu’ajouter des “const” puisse aider ? A première vue, je dirais que oui, mais ça mérite réflexion.

[quote name=‹ Drealmer › date=’ 25 Nov 2004, 11:41’]Je suis en train de me demander si ce genre de choses est une bonne idée niveau performances…

std::string f() { std::string text("coucou"); return text; }

Va-t-il y avoir copie de la chaîne ? Ou le compilo est-il généralement assez futé que pour bien optimiser ça ? Je sais ce que vous allez me dire : « sors-toi les doigts du fion, compile ton code, lance en debug et lis l’assembleur », mais ça risque de me prendre un temps dingue, vu mes connaissances assez légères en asm x86.

Et surtout, imaginez une longue succesion d’appels du genre :

[code]std::string g() {
return f();
}

std::string h() {
return g();
}[/code]

Si il y a copie à chaque fois, ça va finir par faire lourd. Alors, quid ?
edit : bien sûr, dans mon exemple « coucou » est tout ce qu’il y a de plus statique, y’a moyen de faire ça bien plus intelligemment… Le cas qui m’intéresse, c’est celui où la chaîne renvoyée peut être différente pour chaque instance de la classe.

Et aussi, pensez-vous qu’ajouter des « const » puisse aider ? A première vue, je dirais que oui, mais ça mérite réflexion.
[right][post=« 306977 »]<{POST_SNAPBACK}>[/post][/right][/quote]

Alors oui c’est une mauvaise idée :stuck_out_tongue:
Le const n’a aucune incidence niveau execution, c’est une « sécurité » niveau compilateur (a moins que je ne dise une grosse connerie)

L’idée c’est de renvoyer une référence vers la chaine de caractere. Par contre pour ce faire, la string que tu renvoies ne doit pas etre local.

Exemple

std::string& myClass::f()
{
return m_stringDansMaClasse;
}

Par contre ce qui va suivre est trés mal

std::string& myClass::f()
{
std::string localString;
localString = « toto »;
return localString;
}

Mais généralement le compilateur te prévient que tu fais une grosse bourde.

Ce language, c’est du C++ ? Bon, en fait mes souvenirs sont un peu loins. Mais il me semble qu’en C++, le type string est une primitive, donc sera copié à chaque renvoie.
Si je ne dis pas de connerie, le mieux est d’encapsuler la chaîne dans un objet ou une structure pour renvoyer la référence de la string. ou alors remplacer la string par un char* et renvoyer sa référence (&char*).
M’enfin je me gourre peut être

[quote name=‹ kaneloon › date=’ 25 Nov 2004, 12:44’]Ce language, c’est du C++ ? Bon, en fait mes souvenirs sont un peu loins. Mais il me semble qu’en C++, le type string est une primitive, donc sera copié à chaque renvoie.
Si je ne dis pas de connerie, le mieux est d’encapsuler la chaîne dans un objet ou une structure pour renvoyer la référence de la string. ou alors remplacer la string par un char* et renvoyer sa référence (&char*).
M’enfin je me gourre peut être
[right][post=« 306994 »]<{POST_SNAPBACK}>[/post][/right][/quote]

Que racontes-tu ? je ne comprends rien à ce que tu dis. Tu as versé quelques mots clés dans un shaker, bien agité, puis tiré au hasard l’un d’entres-eux et commencé à composer une phrase ? :stuck_out_tongue:

Oui mais non, j’ai bien compris que dans la logique des choses la chaîne doit être copiée. Ce que je me demande, c’est dans la pratique. Voici ce qui se passe à la fin de chaque méthode :

  1. on copie la chaîne
  2. on détruit la chaîne d’origine

Sans aucun traitement entre 1 et 2. Donc, je me dis qu’un compilateur malin, plutôt que de faire une copie d’un objet juste avant de le détruire, va le conserver et l’utiliser en lieu et place de la copie.

La question est donc plutôt de savoir si ce genre d’optimisation est possible, étant données les contraintes imposées par la pile.

Quant à ce qui est du const, c’est effectivement juste une petite garantie lors de la compilation, pas du tout lors de l’exécution. Mais je me disais que le compilateur pouvait se baser dessus pour optimiser un peu le code. Un peu comme avec “inline”, qui n’est finalement qu’un “conseil” pour aider le compilateur.

[quote name=‹ Moktar › date=’ 25 Nov 2004, 13:20’]Que racontes-tu ? je ne comprends rien à ce que tu dis. Tu as versé quelques mots clés dans un shaker, bien agité, puis tiré au hasard l’un d’entres-eux et commencé à composer une phrase ? :stuck_out_tongue:
[right][post=« 307009 »]<{POST_SNAPBACK}>[/post][/right][/quote]

Hum, non, pas vraiment, m’enfin ça paraît si abscon ?
Je vois pas en quoi renvoyer la référence d’un élément au lieu de sa copie paraîsse incompréhensible… M’enfin.

Non, a ma connaissance, aucun compilo ne te propose ce genre d’option. A toi de programmer ce truc le plus proprement possible. De toutes facons, en general, mieux vaut ne pas se fier au comportement des compilateurs pour ce genre de traitement.

Non dans ce cas le compilateur ne fait rien, en tout cas pas celui de visual .net :stuck_out_tongue:

Programme ca comme un grand :stuck_out_tongue:

A priori, tu n’auras aucune optimisation dans le cas d’une utilisation “standard”…

… par contre, si ta méthode est inlinée, alors il est possible (mais loin d’être sûr) que ta chaîne ne soit pas copiée puis détruite.

Disons qu’en régle générale, il vaut mieux soit renvoyer une référence vers un membre de ta classe (ça t’assure qu’il n’y a pas de copie, mais ça t’oblige a tout déclarer dans ta classe), soit prendre en entrée une référence sur une string, que tu rempliras dans ta méthode (et qui donc est à la charge de l’utilisateur).