Оптимизация ненужного копирования строк в векторе <string> - PullRequest
2 голосов
/ 28 сентября 2011

Представление минимального кода для описания проблемы:

struct A {
  vector<string> v;
  // ... other data and methods
};
A obj;
ifstream file("some_file.txt");
char buffer[BIG_SIZE];
while( <big loop> ) {
  file.getline(buffer, BIG_SIZE-1);
  // process buffer; which may change its size
  obj.v.push_back(buffer);  // <------- can be optimized ??
}
...

Здесь 2 раза string создание происходит; 1-й раз для создания фактического string объекта и 2-й раз при создании копии для vector. Демонстрация

Операция push_back() происходит миллионы раз , и я плачу за одно дополнительное выделение столько раз, что для меня бесполезно.

Есть ли способ оптимизировать это?Я открыт для любых подходящих изменений.(не относить это к категории преждевременной оптимизации, потому что push_back() происходит так много раз по всему коду).

Ответы [ 3 ]

3 голосов
/ 28 сентября 2011

Хорошо, вы получаете два распределения, но не оба из них имеют строковое значение: одно из них создает строку, а другое создает только указатель внутри вектора (обратите внимание, что это зависит от компилятора: некоторые компиляторы /Настройки могут действительно создать две строки, но большинство из них не будет).Посмотрите на этот код для демонстрации.

Один из способов оптимизировать его - использовать char * вместо строки в качестве параметра шаблона (не забудьте удалить его вручную перед уничтожением).вектор!)Таким образом, вы избавитесь от одного (самого большого) распределения.В качестве альтернативы, просто используйте собственную реализацию вектора: тогда вы сможете контролировать каждый аспект выделения памяти.

3 голосов
/ 28 сентября 2011

Вы можете попробовать пару вещей.Во-первых, очевидно, чтобы включить оптимизацию на компиляторе. Если вы можете объявить его как vector<const string>, что может помочь.

В противном случае вы можете попробовать что-то вроде:

obj.v.resize(obj.v.size()+1);
obj.v.back().swap(string(buffer));
0 голосов
/ 28 сентября 2011

Вместо буфера в стеке - поместите его в кучу.Тогда используйте вектор указателей.Только один

...