Какой из них более эффективен - метод std :: basic_string :: append или оператор '+'? - PullRequest
0 голосов
/ 30 сентября 2019

Какой из них более эффективен во избежание ненужного копирования метода append или Operator + в C ++ 11 ?

std::string salute = "Hello";
std::string message = salute.append("Namaste");

ИЛИ

std::string salute = "Hello";
std::string message = salute + "Namaste";

Operator + выделяет новый буфер, но он также имеет конструктор ссылок R-значения, который позволяет избежать копирования значения r. Напротив, append не выделяет новый буфер (верно?), Но не имеет перегруженной функции со ссылочным параметром R-значения.

1 Ответ

4 голосов
/ 30 сентября 2019

Оба operator+ и std::basic_string::append имеют перегрузки, которые позволяют избежать ненужных копий строковых литералов - по сравнению с ненужными временными / копиями вы не увидите никакой разницы в производительности во время выполнения.

Кроме того, эти два параметра не являются 'т функционально эквивалентен. std::basic_string::append мутирует объект, тогда как operator+ - нет. В вашем первом примере это приводит к тому, что salute будет «HelloNamaste», а во втором примере - «Hello». Я думаю, что это предполагаемый вариант использования append (он возвращает ссылку, а не новый объект):

std::string salute = "Hello";
salute.append("abc").append("def");

, тогда как создание нового объекта лучше выполнить с помощью operator+. Поскольку намерения обеих функций различны, я не уверен, имеет ли смысл сравнивать их характеристики производительности во время выполнения.

В качестве последнего замечания, operator+ может быть реализован в терминах append, то естьрегистр в заголовке <string> из libcxx:

template<class _CharT, class _Traits, class _Allocator>
inline
basic_string<_CharT, _Traits, _Allocator>
operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs)
{
    basic_string<_CharT, _Traits, _Allocator> __r(__lhs.get_allocator());
    typename basic_string<_CharT, _Traits, _Allocator>::size_type __lhs_sz = __lhs.size();
    typename basic_string<_CharT, _Traits, _Allocator>::size_type __rhs_sz = _Traits::length(__rhs);
    __r.__init(__lhs.data(), __lhs_sz, __lhs_sz + __rhs_sz);
    __r.append(__rhs, __rhs_sz);
    return __r;
}
...