Abhishek Chandel
Abhishek Chandel

Reputation: 1354

Returning an empty string : efficient way in c++

I have 2 ways of returning an empty string from a function.

1)

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

2)

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

which one is more efficient and why?

Upvotes: 58

Views: 74468

Answers (3)

bobobobo
bobobobo

Reputation: 67224

These are all 100% identical performance-wise

string construction comparison with identical perf

I threw in another common approach where you return a superglobal variable (practically people usually keep these as a static in a StringUtility class):

// Super global variable
string EmptyString;

string getEmptyQuotes() { return ""; }
string getBraces()      { return {}; }
string getCtor()        { return string(); }
string getVar()         { return EmptyString; }

So it's just a question of style, I guess

Upvotes: -1

Baldrickk
Baldrickk

Reputation: 4409

Gcc 7.1 -O3 these are all identical, godbolt.org/z/a-hc1d – jterm Apr 25 at 3:27

Original answer:

Did some digging. Below is an example program and the relevant assembly:

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();
}

Assembly:

__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

This was compiled with -std=c++11 -O2.

You can see that there is quite a lot more work for the return ""; statement and comparably little for return std::string and return {}; (these two are identical).

As Frerich Raabe said, when passing an empty C_string, it still needs to do processing on it, instead of just allocating memory. It seems that this can't be optimised away (at least not by GCC)

So the answer is to definitely use:

return std::string();

or

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

Although unless you are returning a lot of empty strings in performance critical code (logging I guess?), the difference is going to still be insignificant.

Upvotes: 77

Frerich Raabe
Frerich Raabe

Reputation: 94299

The latter version is never slower than the first. The first version calls the std::string constructor taking a C string, which then has to compute the length of the string first. Even though that's fast to do for an empty string, it's certainly not faster than not doing it at all.

Upvotes: 4

Related Questions