оптимизация записи в STL вектор

171
07 октября 2018, 14:30

У меня какая-то странная ситуация, которую никак не могу понять.

Есть такой код:

typedef std::vector<figure_info_t> figure_t;
typedef std::vector<figure_t> figures_t;
void
add_result
(figures_t& results, figure_info_t* localResult, const int figuresAmount)
{
    figure_t figuresData;
    for (int index = 0; index < figuresAmount; index++)
    {
        figuresData.push_back(localResult[index]);
    }
    results.push_back(figuresData);
}

Тут мне что-то подумалось, что написано как-то по детски неуклюже и переписал вот так:

void
add_result
(figures_t& results, figure_info_t* localResult, const int figuresAmount)
{
    results.push_back(figure_t(localResult, localResult + figuresAmount));
}

Дешево и сердито

Вопрос:

Но почему-то новый код стал работать медленнее, совсем чуть-чуть, но стабильно (общая работа приложения замедлилась на 2%, а ведь в ней вызов add_result не является очень уж частым).

Так вот: почему могла возникнуть такая ситуация? Вроде же и код короче и используются возможности std::vector без лишнего самопала. Так почему же идет замедление?

Answer 1

Логика подсказывает:

figure_t(localResult, localResult + figuresAmount)

это вызов конструктора(напишем его примерное представление)

template<typename In>
std::vector<figure_info_t>::vector<figure_info_t>(In first, In last)
{        
    const size_t n = std::distance(first, last);
    // выделяется неинициализированная память под n штук обьектов                 
    // инициализируется значениями [first, last[
}

Практически делается то же самое, что и сделано при первом варианте. Вызов встроенного метода push_back в n раз может не быть медленне( выделяется память под один обьект figure_info_t), чем поиск памяти под n обьектов figure_info_t , особенно если эти обьекты большие. По моему время выполнения зависит и от железа и от компилятора(хотя второй вариант, в основном, должен быть быстрее), но, по любому, разница должна быть незначительная.

P.S. короткий ответ: на разных компьютерах получите разный результат разницы времены выполнения этих вариантов.

READ ALSO
Инициализация массива указателей

Инициализация массива указателей

Разбираюсь в чужом кодеНасколько правомерно так инициировать:

167
Как зарезервировать память для MapViewOfFileEx?

Как зарезервировать память для MapViewOfFileEx?

Работая с мапингом под виндой, столкнулся с такой проблемой, не получается зарезервировать буфер под MapViewOfFileEx

174
Можно ли динамически определить, как был создан объект - на куче или в стеке?

Можно ли динамически определить, как был создан объект - на куче или в стеке?

Например проверять объект при очищении контейнера:

158