У меня есть два способа вернуть пустую строку из функции.
1)
std::string get_string()
{
return "";
}
2)
std::string get_string()
{
return std::string();
}
какой из них более эффективен и почему?
У меня есть два способа вернуть пустую строку из функции.
1)
std::string get_string()
{
return "";
}
2)
std::string get_string()
{
return std::string();
}
какой из них более эффективен и почему?
Gcc 7.1 -O3 все они идентичны, godbolt.org/z/a-hc1d - 25 апреля в 3:27
Покопался. Ниже приведен пример программы и соответствующей сборки:
Код:
#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();
}
Монтаж:
__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
Это было скомпилировано с -std=c++11 -O2
.
Вы можете видеть, что для return "";
достаточно много работы return "";
оператор и сравнительно мало для return std::string
и return {};
(эти два идентичны).
Как сказал Фрерих Раабе, передавая пустую C_string
, он все равно должен обрабатывать ее, а не просто выделять память. Кажется, что это не может быть оптимизировано далеко (по крайней мере, не GCC)
Таким образом, ответ должен определенно использовать:
return std::string();
или же
return {}; //(c++11)
Хотя, если вы не возвращаете много пустых строк в критичном для производительности коде (логирование, я полагаю?), Разница все равно будет незначительной.
Последняя версия никогда не медленнее первой. Первая версия вызывает конструктор std::string
, взяв строку C, которая затем должна сначала вычислить длину строки. Даже если это быстро сделать для пустой строки, это, конечно, не быстрее, чем вообще не делать.