web-dev-qa-db-ja.com

空の文字列を返す:C ++での効率的な方法

関数から空の文字列を返す方法は2つあります。

1)

std::string get_string()
{
   return "";
}

2)

std::string get_string()
{
   return std::string();
}

どちらがより効率的で、なぜですか?

22

Gcc 7.1 -O3これらはすべて同一です、godbolt.org/z/a-hc1d – jterm Apr 25 at 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 std::stringreturn {};にはほとんどないことがわかります(これら2つは同じです)。

Frerich Raabeが言ったように、空のC_stringを渡すときは、単にメモリを割り当てるのではなく、それを処理する必要があります。これは(少なくともGCCではなく)最適化することはできないようです

だから答えは間違いなく使用することです:

return std::string();

または

return {};   //(c++11)

ただし、パフォーマンスが重要なコード(おそらくログに記録されますか?)で大量の空の文字列を返さない限り、違いはわずかです。

41
Baldrickk

後者のバージョンが最初のバージョンより遅くなることはありません。最初のバージョンは、C文字列を取得するstd::stringコンストラクターを呼び出します。このコンストラクターは、最初に文字列の長さを計算する必要があります。空の文字列を処理するのは高速ですが、まったく実行しないよりは確実に高速ではありません。

2
Frerich Raabe