Создать и вернуть вектор строк - самое эффективное решение?
В функции-член я хочу вернуть недавно созданный вектор строк. Какая версия наиболее эффективна с точки зрения выделения памяти и вызова конструктора? theString(i)
возвращает const std::string &
std::vector<std::string> result(depth());
for(int i=0;i<depth;i++) {
result[i] = theString(i);
}
или же
std::vector<std::string> result;
result.reserve(depth());
for(int i=0;i<depth;i++) {
result.emplace_back(theString(i));
}
Мне кажется, что:
- Решение 1 сначала строит каждую пустую строку, затем копирует-присваивает их => не идеально
- Решение 2 лучше, так как оно будет копировать-конструировать каждую строку, в то время как векторные данные выделяются один раз
reserve
(или есть еще более эффективное решение?)
1 ответ
Невозможно дать общий ответ: в зависимости от вашего компилятора, реализации стандартной библиотеки, чем вы используете, целевого процессора и окружающего исходного кода, испускаемый код может отличаться. Кроме того, то, является ли одно или другое решение более быстрым, также может зависеть от эффектов кэша или эффектов переключения потоков, вызванных различным планированием.
Так что, к сожалению, нет общего ответа: измерьте с вашей настройкой.
При этом позвольте мне предложить двух других кандидатов; кандидат 3:
// The simplest code is always easier to read:
std::vector<std::string> result;
for (size_t i = 0; i < depth; ++i) { result.emplace_back(theString(i)); }
Я был бы удивлен, если бы это было намного хуже, чем ваш кандидат 2. Он опирается на vector
Амортизированная постоянная emplace_back
и тот факт, что перемещение строк дешево (по сравнению с копированием).
И кандидат 4:
// If no copy is necessary, then no copy is cheaper:
std::vector<std::string_view> result; // or another "StringRef" alternative
for (size_t i = 0; i < depth; ++i) { result.emplace_back(theString(i)); }
Последний опирается на string_view
: не принадлежащая ссылка на строку, которую очень просто реализовать (в основном, пара size_t
а также char const*
), но только в том случае, если указанная строка гарантированно переживет последнее использование string_view
,