Более эффективно использовать «string.clear ()» или «string = ''»? [Закрыто]

Является ли более эффективным использование string.clear() или будет более оптимизированным, если я использую string = '' для очистки содержимого строки?

Следует ли мне всегда использовать библиотечную функцию (string.clear()) или более "простой" (string = '') в качестве лучшей практики?

2
задан 31.03.2017, 13:50
2 ответа

Используя string::operator=(), происходит следующее:

  1. Производится пустая цепь в секции данных, чтобы мочь получать Ваш адрес.
  2. Производится код, чтобы перемещать Ваш адрес в string::operator=()
  3. string::operator=() он прочитает адрес, который проходит с ним, чтобы получать размер цепи, которая прошла с ним как аргумент.
  4. Оператор делает Вашу работу.
  5. Оператор возвратит результат.

Давайте помнить, что класс std::string она - владелица цепей, которая манипулирует: когда ему распределяется стоимость, он копирует цепь во внутренний буфер, чтобы делать ее независимой от первоначальной цепи. Это поддерживает некое управление memória, и необходимость знать размер цепей, которые распределяются им.

Используя string.clear(), происходит следующее:

  1. Он называется в функцию string.clear(), без аргументов, и эта делает Вашу работу.
  2. Он совсем не возвращается.

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

Я ИЗДАЮ

Типичное, неполное осуществление и без шаблонов, только как дидактический пример, не будучи изнурительной:

class string {
private:
 char *buffer;
 size_t alloc; // Tamaño del buffer.
 size_t length; // Longitud real de la cadena.

public:
 string &operator=( const char *other ) {
  size_t other_size = strlen( other ); // Tamaño de la cadena a asignar.
  if( other_size <= ( alloc - 1 ) ) { // Utilizamos un byte para el 0 al final.
   // La nueva cadena cabe dentro del buffer.
   if( other_size != 0 ) // la nueva cadena no está vacía.
    memcpy( alloc, other, other_size + 1); // La copiamos, incluido el 0 final.
   length = other_size; // Nueva longitud de la cadena.
   return *this;
  }
  /*
   ... Resto de la implementación ...
  */
 }
 inline void clear( ) {
  length = 0;
  *buffer = 0; // un 0 al final, por si acaso.
 }

 /*
  ... Resto de métodos ...
 */
};

Выполняется строго стандарт:

  • Время выполнения operator=() он линейный (он зависит от длины цепи other).
  • Время выполнения clear() это всегда тот же самый. В стандарте, определяется поведение максимальной продолжительности службы, а именно clear() выполни стандарт, так как он это улучшает.

Если мы наблюдаем код примера:

string &operator=( const char *other ) {
 size_t other_size = strlen( other );
 . . .

Первое, что мы делаем, состоит в том, чтобы получать размер новой цепи. Это критическая, неизбежная точка. Мы должны знать размер, если или если. Этот вызов в strlen( other ) она - виновница, которой clear() будьте гораздо быстрее.

Еще препятствуя времени размещения и доставления элементов батарейки, функции clear() она гораздо быстрее, чем + operator=(). Более того, еще имея в виду практически любую возможную оптимизацию (размещать маленькие цепи не-нравится внутри указателя, чтобы управление memória уберегается...), функция clear() почти всегда она будет быстрее, потому что уберегается подтверждать размеры. Могут быть случаи, в которых распределять пустую цепь было бы равным быстрого, что clear(), но они будут считаться и высоко зависимые от составителя и осуществления.

Размышляя немного, и входя в мыслительные мастурбации, единственный случай, который приходит в голову мне, в котором оба были сравнимыми в скорости, состоит в том, чтобы у составителя была конкретная оптимизация для случая пустых цепей, и осуществление string узнало их и будьте способен использовать их (собственный, сходный тип в nullptr, чтобы показывать указатель пустой цепи). И он не будет применимым во всех случаях.

Обобщая, и как я сказал раньше, лучше звонить в специфические функции, чем в том, чтобы использовать характерные механизмы.

5
ответ дан 24.11.2019, 12:42
  • 1
    Благодарен за correcci и # 243; n, но я не соглашаюсь с в и # 241; adir точка в список действий, позвонив в string.clear (). Призыв к funci и # 243; n возможно обобщать в 3 шагах: размещать аргументы в батарейке, реализовывать вызов, и доставать результат батарейки, как он делает string:: operator = (). string.clear (), без аргументов и без возврата, препятствуй точкам предыдущий 1 и 3. Он из-за этого, из-за чего coloqu и # 233; единственный элемент в Вашем descripci и # 243; n. – Trauma 08.11.2016, 10:11
  • 2
    Это в и # 241; ad и # 237; и #250; nicamente из-за связности, так как в случае asignaci и # 243; n ты отделил работу внутри funci и # 243; n и devoluci и # 243; n той же самой. В любом случае correcci и # 243; n он просто est и # 233; костариканская. Помеченный в сером est и # 225; подумавший, чтобы выделяться c и # 243; я говорю, так как он обычно включает выделенный синтаксиса и в и # 241; adir плоский текст может вызывать, что ответ менее читабельный. В любом случае ничто не запрещает тебе вновь издавать вопрос, чтобы оставлять ее в твой вкус... ты в конце концов - автор той же самой:) – eferion 08.11.2016, 10:39
  • 3
    Я не вижу, что funció n clear из твоего примера implementació n из string удалите попросившие данные ¿ ты сделал algú n benchmark включая delete [] buffer в clear? – PaperBirdMaster 11.11.2016, 14:35
  • 4
    ¿ И для того, чтобы он хочет удалить их, если он помещает \0 в первый характер и помечает длину как 0? с этим это достаточно. Буфер сохраняет для будущих использований до тех пор, пока инстанция не будет разрушенной. Это implementació n больше bá sica всех. Самые современные используют сам указатель, чтобы сохранять цепь, если он помещается, и уберегаются управление буфера, если ты, например, только используешь ее, чтобы сохранять одну " ". – Trauma 11.11.2016, 14:38

Согласно доступной документации в cppreference на operator = и функция clear у нас есть следующее:

std::basic_string::operator =

  1. basic_string& operator=( const basic_string& str ): Линейная комплексность, зависимая от размера str.
  2. basic_string& operator=( basic_string&& ): Линейная комплексность, зависимая от размера цепи (this) так как каждый из размещенных символов они должны быть удаленными.
  3. basic_string& operator=( const CharT* s ): Линейная комплексность, зависимая от длины цепи, указанной из-за s.
  4. basic_string& operator=( CharT ): Постоянная комплексность.
  5. basic_string& operator=( std::initializer_list<CharT> sv): Линейная комплексность, зависимая от размера sv.

Линейная комплексность значит, что цена вычисления растет линейно согласно параметру, а именно: больше займите параметр больше цена вычисления будет иметь. В других словах, если бы распределять каждый характер параметра стоило 0,0001 секунд, медлило бы 1 секунда с тем, чтобы распределять себе цепь 10.000 символов.

Постоянная комплексность значит, что цена вычисления - та же самая независимо от параметров, на которых он производится.

std::basic_string::clear

Комплексность этой функции линейная зависимо размер цепи, который нужно удалять. А именно: если удалять каждый характер string он стоил 0,0001 секунд медлили бы 1 секунда с тем, чтобы удалять цепь 10.000 символов.

string.clear() против string = ' '

Чтобы начинать обе функции они делают различные вещи. clear удали контент цепи (она переходит к тому, чтобы быть пустой и иметь длину 0 символов) в то время как string = ' ' распредели характер он раздвинул цепь (он переходит к тому, чтобы содержать характер место и длину 1 характера).

Однажды осветленный это, мы видим, что ты используешь перегрузку 4 из оператора = std::string, уникум, комплексность которого постоянная. Он будет зависеть насколько дорогой будьте этой постоянной комплексностью, чтобы знать, более или менее дорого ли, который цепь удалять, но несомненно, будет существовать размер цепи, стертое место которой будет дороже, который использовать string = ' '.

Что говорит стандарт?

Лично он не придает квадратную форму мне тому, что распределять характер было линейной комплексности; так что я консультировал Ваши требования в стандарте C ++ (перевод мой):

21.4.2 basic_string строители и операторы ассигнования

basic_string& operator=(charT c);

возврати: *this = basic_string(1,c).

Кажется, что, чтобы распределять характер, строится один string ненастье, которое после распределяется в string, так что будет использован asignador движения (он перегружает 2), комплексность которого линейная в зависимости от размера настоящего string так как нужно удалять старые контенты.

Потрясение.

string.clear() и string = ' ' они делают различные вещи, но у них есть очень казавшаяся цена вычисления, так как обе функции должны удалять предыдущий контент, выбирать один или другой будет зависеть от, если ты захочешь покончить с пустой цепью или с цепью с местом.

1
ответ дан 24.11.2019, 12:42