Je suis à la recherche d'un document qui explique simplement (avec le moins
possible de langage machine) les optimisations réalisées par le compilateur.
Régulièrement, je veux faire une fonction qui retourne un type un peu
complexe (des vecteurs, des strings...). Je fais donc
std::vector<std::string> foo()
{
std::vector<std::string> data;
//remplit data
return data;
}
int main()
{
std::vector<std::string> result = foo();
}
Théoriquement, il doit y avoir une construction de std::vector<std::string>
dans foo, un constructeur par copie dans main, et l'appel au destructeur de
l'objet créé dans foo. C'est dommage (surtout si data contient beaucoup de
données). Une optimisation simple consiste à faire
void foo(std::vector<std::string>& data)
{
//remplit data
}
int main()
{
std::vector<std::string> result; foo(result);
}
ou encore (un peu moins bien, mais toujours mieux que l'original)
std::vector<std::string> foo()
{
std::vector<std::string> data;
//remplit data
return data;
}
int main()
{
std::vector<std::string> result; result.swap(foo());
}
Dans la premiere optimisation, on n'a plus qu'une seul construction de
std::vector<std::string>. Dans la seconde, on a pas de duplication des
données en mémoire.
Est ce que je peux compter sur le compilo pour faire une de ces deux
optimisations ?
Merci
--
Vincent
PS: est ce que fclc++ est le groupe le plus adapté pour parlé de ca ?
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Jean-Marc Bourguet
"Vincent Lascaux" writes:
Je suis à la recherche d'un document qui explique simplement (avec le moins possible de langage machine) les optimisations réalisées par le compilateur.
Ça va dépendre du compilateur...
Dans ton cas particulier:
std::vector<std::string> foo() { std::vector<std::string> data; //remplit data return data; } Une optimisation simple consiste à faire void foo(std::vector<std::string>& data) { //remplit data }
Le compilateur est autorisé (mais ce n'est pas certain que tous le font) à la faire même si elle est détectable par un programme (en général, les optimisations sont sous la régle du "as if": on ne peut pas les faire si elles changent le comportement d'un programme conforme). Un mot clé pour faire une recherche la dessus est NRVO (Named Return Value Optimisation).
A+
-- Jean-Marc FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html Site de usenet-fr: http://www.usenet-fr.news.eu.org
"Vincent Lascaux" <nospam@nospam.org> writes:
Je suis à la recherche d'un document qui explique
simplement (avec le moins possible de langage machine) les
optimisations réalisées par le compilateur.
Ça va dépendre du compilateur...
Dans ton cas particulier:
std::vector<std::string> foo()
{
std::vector<std::string> data;
//remplit data
return data;
}
Une optimisation simple consiste à faire
void foo(std::vector<std::string>& data)
{
//remplit data
}
Le compilateur est autorisé (mais ce n'est pas certain que
tous le font) à la faire même si elle est détectable par un
programme (en général, les optimisations sont sous la régle
du "as if": on ne peut pas les faire si elles changent le
comportement d'un programme conforme). Un mot clé pour
faire une recherche la dessus est NRVO (Named Return Value
Optimisation).
A+
--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Je suis à la recherche d'un document qui explique simplement (avec le moins possible de langage machine) les optimisations réalisées par le compilateur.
Ça va dépendre du compilateur...
Dans ton cas particulier:
std::vector<std::string> foo() { std::vector<std::string> data; //remplit data return data; } Une optimisation simple consiste à faire void foo(std::vector<std::string>& data) { //remplit data }
Le compilateur est autorisé (mais ce n'est pas certain que tous le font) à la faire même si elle est détectable par un programme (en général, les optimisations sont sous la régle du "as if": on ne peut pas les faire si elles changent le comportement d'un programme conforme). Un mot clé pour faire une recherche la dessus est NRVO (Named Return Value Optimisation).
A+
-- Jean-Marc FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html Site de usenet-fr: http://www.usenet-fr.news.eu.org
Matthieu Moy
Jean-Marc Bourguet writes:
"Vincent Lascaux" writes:
Je suis à la recherche d'un document qui explique simplement (avec le moins possible de langage machine) les optimisations réalisées par le compilateur.
Ça va dépendre du compilateur...
Dans ton cas particulier:
En fait, je crois que le mieux dans ces cas là est encore de se faire un petit benchmark pour verifier expérimentalement si l'optimisation est faite et dans quelles conditions.
-- Matthieu
Jean-Marc Bourguet <jm@bourguet.org> writes:
"Vincent Lascaux" <nospam@nospam.org> writes:
Je suis à la recherche d'un document qui explique
simplement (avec le moins possible de langage machine) les
optimisations réalisées par le compilateur.
Ça va dépendre du compilateur...
Dans ton cas particulier:
En fait, je crois que le mieux dans ces cas là est encore de se faire
un petit benchmark pour verifier expérimentalement si l'optimisation
est faite et dans quelles conditions.
Je suis à la recherche d'un document qui explique simplement (avec le moins possible de langage machine) les optimisations réalisées par le compilateur.
Ça va dépendre du compilateur...
Dans ton cas particulier:
En fait, je crois que le mieux dans ces cas là est encore de se faire un petit benchmark pour verifier expérimentalement si l'optimisation est faite et dans quelles conditions.
-- Matthieu
moy
Salut,
Les compilo implementent en fait la premiere solution que tu proposes, cad qu'ils reservent l'espace memoire necessaire dans la fonction appelante, en passsant un argument supplementaire a la fonction appellee qui est un pointeur vers ton espace memoire.
Cette optimisation n'est en general possible que si tous les "return" de la fonction appellee retournent la meme variable (d'ou le nom "Named Return Value Optimization"), ou s'il n'y a qu'un seul point de retour (auquel cas "return Obj();" sera aussi optimise).
A la difference de ta simulation en C++, il n'y a pas de construction a proprement parler dans la fonction appelante.
Le mieux comme dit Mathieu, c'est de tester, en faisant imprimer quelque chose par le copy-constructeur, qu'il est appelle ou pas. Un remarque concernant une reponse precedente, la norme dit qu'une implementation est libre de "sucrer" la creation de variables temporaires, meme s'il y a des effets de bords attendus. C'est le cas pour le retour de fonction ici, mais aussi pour le passage de parametres, les throw/catch ...
Yannick
Salut,
Les compilo implementent en fait la premiere solution
que tu proposes, cad qu'ils reservent l'espace memoire necessaire
dans la fonction appelante, en passsant un argument supplementaire
a la fonction appellee qui est un pointeur vers ton espace memoire.
Cette optimisation n'est en general possible que si tous les "return"
de la fonction appellee retournent la meme variable (d'ou le nom
"Named Return Value Optimization"), ou s'il n'y a qu'un seul point de retour
(auquel cas "return Obj();" sera aussi optimise).
A la difference de ta simulation en C++, il n'y a pas de construction
a proprement parler dans la fonction appelante.
Le mieux comme dit Mathieu, c'est de tester, en faisant imprimer quelque
chose par le copy-constructeur, qu'il est appelle ou pas.
Un remarque concernant une reponse precedente, la norme dit
qu'une implementation est libre de "sucrer" la creation de variables
temporaires, meme s'il y a des effets de bords attendus. C'est le cas
pour le retour de fonction ici, mais aussi pour le passage de parametres,
les throw/catch ...
Les compilo implementent en fait la premiere solution que tu proposes, cad qu'ils reservent l'espace memoire necessaire dans la fonction appelante, en passsant un argument supplementaire a la fonction appellee qui est un pointeur vers ton espace memoire.
Cette optimisation n'est en general possible que si tous les "return" de la fonction appellee retournent la meme variable (d'ou le nom "Named Return Value Optimization"), ou s'il n'y a qu'un seul point de retour (auquel cas "return Obj();" sera aussi optimise).
A la difference de ta simulation en C++, il n'y a pas de construction a proprement parler dans la fonction appelante.
Le mieux comme dit Mathieu, c'est de tester, en faisant imprimer quelque chose par le copy-constructeur, qu'il est appelle ou pas. Un remarque concernant une reponse precedente, la norme dit qu'une implementation est libre de "sucrer" la creation de variables temporaires, meme s'il y a des effets de bords attendus. C'est le cas pour le retour de fonction ici, mais aussi pour le passage de parametres, les throw/catch ...