Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which combination of overloads is most performant?

I have a function like this:

void init_str(std::string _s)
{
    std::string s{_s};
}

And I want to have an optimization by allowing a const char* overload to avoid creating a temporary std::string.

void init_str(const char* c)
{
    std::string s{c};
}

But I can also use forwarding as well.

template<typename T>
void init_str(T&& t)
{
    std::string s{std::forward<T>(t)};
}

But the preference of overloads by the compiler is:

  • const char*
  • forwarding
  • std::string

So what combination of overloads should I prefer?

like image 364
user4380656 Avatar asked Nov 20 '25 23:11

user4380656


1 Answers

Assuming c++11 or better, the most performant solution is the one you have not yet tried:

void init_str(std::string s)
{
  // just use s
}

Because copy elision will ensure that no un-necessary temporary is constructed at all.

this constructs s using the std::string(const char*) constructor (1 construction total):

init_str("xxx");

this constructs s with a copy constructor:

std::string x; // 1 constructor
init_str(x);   // 1 copy constructor

this constructs s with a move constructor

std::string x;            // 1 constuctor
init_str(std::move(x));   // 1 move constructor

this does not actually create the temporary at all:

std::string get_str() {
    std::string s("xxx");   // 1 constructor, but...
    return s;               // ...because of RVO it's constructed at the call site
}

init_str(get_str());        // ... which is actually the constructor of s in init_str's arg list
// ... total constructors: 1
like image 197
Richard Hodges Avatar answered Nov 23 '25 13:11

Richard Hodges



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!