Eric M Schmidt Eric M Schmidt - 2 months ago 7
C++ Question

Why does omitting the push_back make the loop run slower?

Consider this program, which I am compiling on Cygwin with gcc 5.4.0 and command line

g++ -std=c++14 -Wall -pedantic -O2 timing.cpp -o timing
.

#include <chrono>
#include <iostream>
#include <string>
#include <vector>

std::string generateitem()
{
return "a";
}

int main()
{
std::vector<std::string> items;

std::chrono::steady_clock clk;
auto start(clk.now());

std::string item;
for (int i = 0; i < 3000000; ++i)
{
item = generateitem();
items.push_back(item); // *********
}

auto stop(clk.now());
std::cout
<< std::chrono::duration_cast<std::chrono::milliseconds>
(stop-start).count()
<< " ms\n";
}


I consistently get a reported time of around 500 ms. However, if I comment out the starred line, thus omitting the
push_back
to the
vector
, the time reported is around 700 ms.

Why does not pushing to the
vector
make the loop run slower?

Answer

I've run the test now, and the problem is that in the push_back version, the item string is not being deallocated. Changing the code to:

#include <chrono>
#include <iostream>
#include <string>
#include <vector>

std::string generateitem()
{
    return "a";
}

int main()
{

    std::chrono::steady_clock clk;
    auto start(clk.now());
{
    std::vector<std::string> items;
    std::string item;
    for (int i = 0; i < 3000000; ++i)
    {
        item = generateitem();
        items.push_back(item); // *********
    }
}
    auto stop(clk.now());
    std::cout
        << std::chrono::duration_cast<std::chrono::milliseconds>
            (stop-start).count()
        << " ms\n";
}

Gives the expected behaviour of, on my CygWin machine, about the same time for both options, as we measure all the deallocations this time.

Comments