NRVO для C ++ std :: string - PullRequest
       38

NRVO для C ++ std :: string

2 голосов
/ 03 июня 2019

Я попытался найти некоторую информацию о std :: string Named Return Value Optimization (NVRO). Я даже не уверен, применимо ли это, но мне интересно, что было бы лучше с точки зрения читаемости и производительности POV.

std::string first(const bool condition)
{
    std::string info = "This";
    info += condition 
        ? " is" 
        : " irrelevant";  //.append()

    info += " info.";

    return info; // nrvo here?
}

std::string second(const bool condition)
{
    const auto firstPart = "First part";
    const auto anotherPart = condition 
        ? " second part" 
        : " irrelevant ";  //.append()

    return std::string{}.append(firstPart).append(anotherPart);
}

std::string third(const bool condition)
{
    //would avoid due to poor readability if strings are long
    return std::string{}
        .append("First part")
        .append(condition ? " second" : "irrelevant");
}

int main()
{
    // printf("Hello World");
    const auto irrelevant {true};

    std::cout<<first(irrelevant)<<std::endl;
    std::cout<<second(irrelevant)<<std::endl;
    std::cout<<third(irrelevant)<<std::endl;

    return 0;
}

Как в комментариях:

  1. Будет ли nvro исполняться в «фристе»?

  2. Есть ли лучший (более чистый / эффективный) способ решения этой проблемы?

Мое намерение - создать вспомогательную функцию, которая объединит правильную строку на основе заданного параметра

Ответы [ 2 ]

3 голосов
/ 03 июня 2019
  1. В C ++ 11 и 14 в этом случае разрешено копирование . Начиная с C ++ 17, оптимизация возвращаемого значения является обязательной (и больше не рассматривается как copy elision ).

  2. Не то чтобы я мог это увидеть, посмотрев на три функции-кандидата @ godbolt , но я не особо разбираюсь в ассемблере. Это может выглядеть немного чище, хотя:

    std::string fourth(const bool condition) {
        return std::string{"First part "} += (condition ? "second" : "irrelevant");
    }
2 голосов
/ 03 июня 2019

Ваш первый вопрос был задан @ Ted_Lyngmo

Если вы действительно сомневаетесь в производительности (и измерения подтверждают, что эта функция является вашей горячей точкой), std::string в этом случае слишком тяжел.Он не допускает всех оптимизаций времени компиляции, таких как constexpr

Я предлагаю использовать std::string_view

#include <string_view>

constexpr std::string_view print(const bool condition) {
    if (condition){
        return "This is relevant info";
    } else {
        return "This is irrelevant info";
    }
}

int main() {
    std::string_view info = print(false);
    return info.size();
}

Эта программа будет полностью оптимизированаот

main:
        mov     eax, 23
        ret

Если вы используете print(true), он изменится на

main:
        mov     eax, 21
        ret

Таким образом, также, если вы будете использовать предложение позже, оно будет лучше всего оптимизировано компилятором.

Примечание. Вы можете использовать string_view , только если у вас есть компилятор C ++ 17.

...