OVH Cloud OVH Cloud

Quelles optimisation fait le compilo ?

3 réponses
Avatar
Vincent Lascaux
Bonjour,

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 ?

3 réponses

Avatar
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

Avatar
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


Avatar
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