J'ai 2 façons de renvoyer une chaîne vide à partir d'une fonction.
1)
std::string get_string()
{
return "";
}
2)
std::string get_string()
{
return std::string();
}
lequel est le plus efficace et pourquoi?
Gcc 7.1 -O3 ce sont tous identiques, godbolt.org/z/a-hc1d - jterm 25 avril à 3:27
A creusé. Voici un exemple de programme et l'Assemblée appropriée:
Code:
#include <string>
std::string get_string1(){ return ""; }
std::string get_string2(){ return std::string(); }
std::string get_string3(){ return {}; } //thanks Kerrek SB
int main()
{
get_string1();
get_string2();
get_string3();
}
Assemblée:
__Z11get_string1v:
LFB737:
.cfi_startproc
pushl %ebx
.cfi_def_cfa_offset 8
.cfi_offset 3, -8
subl $40, %esp
.cfi_def_cfa_offset 48
movl 48(%esp), %ebx
leal 31(%esp), %eax
movl %eax, 8(%esp)
movl $LC0, 4(%esp)
movl %ebx, (%esp)
call __ZNSsC1EPKcRKSaIcE
addl $40, %esp
.cfi_def_cfa_offset 8
movl %ebx, %eax
popl %ebx
.cfi_restore 3
.cfi_def_cfa_offset 4
ret $4
.cfi_endproc
__Z11get_string2v:
LFB738:
.cfi_startproc
movl 4(%esp), %eax
movl $__ZNSs4_Rep20_S_empty_rep_storageE+12, (%eax)
ret $4
.cfi_endproc
__Z11get_string3v:
LFB739:
.cfi_startproc
movl 4(%esp), %eax
movl $__ZNSs4_Rep20_S_empty_rep_storageE+12, (%eax)
ret $4
.cfi_endproc
Ceci a été compilé avec -std=c++11 -O2
.
Vous pouvez voir qu'il y a beaucoup plus de travail pour le return "";
déclaration et relativement peu pour return std::string
et return {};
(ces deux sont identiques).
Comme l'a dit Frerich Raabe, lors du passage d'un C_string
, il doit encore faire un traitement dessus, au lieu d'allouer simplement de la mémoire. Il semble que cela ne puisse pas être optimisé (du moins pas par GCC)
Donc, la réponse est d'utiliser définitivement:
return std::string();
ou
return {}; //(c++11)
Bien qu'à moins que vous ne retourniez beaucoup de chaînes vides dans du code critique pour les performances (enregistrement, je suppose?), La différence restera insignifiante.
Cette dernière version n'est jamais plus lente que la première. La première version appelle le std::string
constructeur prenant une chaîne C, qui doit ensuite calculer la longueur de la chaîne en premier. Même si c'est rapide à faire pour une chaîne vide, ce n'est certainement pas plus rapide que de ne pas le faire du tout.