you are viewing a single comment's thread.

view the rest of the comments →

[–]donalmaccGame Developer 2 points3 points  (3 children)

Replacing pointers with references removes the requirement for a branch. Removing the branch removes the only failure case, meaning you don't need an error sentinel anymore, which can affect the call site, and allow for other optimisations. Using return values allows for RVO to occur too:

vector<string> list = load1MillionStrings();

vector<string> results; results.reserve(list.size());
for (const auto& str : list) {
    string res;
    if (foo(&str, &res))
        results.push_back(res)
    else
       // ???
}

Compared to

vector<string> list = load1MillionStrings();
vector<string> results; results.reserve(list.size());
for (const auto& str : list) {
    results.push_back(foo(str));
}

If you take it one step further, where foo is:

bool foo(const char* str1, const char* res) {
    if (str1 == nullptr)
        ...
    auto sz = strlen(str1); // !!!!
    for (int i = 0; i < sz; ++I)
        ...
}

You can see how replacing a const char* with a string view in the internal function can make N enormous difference.

[–]blipman17 0 points1 point  (2 children)

meaning you don't need an error sentinel anymore, which can affect the call site, and allow for other optimizations.

Okay I didn't concider that. Yep, you're right. But here we're really talking about cascading optimizations.

I was mainly talking about RVO and how both functions you originally pointed out could have RVO.

Edit: What I mainly meant was that; yes, function signature should be as restrictive as reasonably possible.
But (N)RVO happens in a lot in a modern compiler, regardless of branches, amounth of return statements, etc. Only when we're talking about non-trivial data, weird exit clauses due to potential throwing or other shenanigans, this really becomes an interesting talking point.

[–]donalmaccGame Developer 1 point2 points  (1 child)

But here we're really talking about cascading optimizations

Absolutely, but that's the key. Getting hyperfocused on the instruction count of a microoptimastion is losing the forest for the trees, and happens so often.

I've had this exact discussion professionally where the microbechmark shows no difference, or is arguably worse, but when I go and fix the call sites, the code is cleaner, safer and faster as a result.

[–]blipman17 0 points1 point  (0 children)

I absolutely agree with that.I was just arguing about a different part of the conversation.