2

Version 1 (1572.38ms):

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

int main(int argc, char* argv[])
{
    std::chrono::time_point<std::chrono::steady_clock> startTime = std::chrono::steady_clock::now();
    int n = 1000000;
    int m = 1000;

    for (int k = 0; k < m; k++)
    {

        std::vector<int> array(0);

        array.reserve(n);

        for (int i = 0; i < n - 10; i++)
        {
            array.push_back(i);
        }
    }

    auto time = std::chrono::steady_clock::now() - startTime;
    std::cout   << "Elapsed time: "
            << std::chrono::duration<double, std::milli>(time).count()
            << " ms\n";
    return 0;
}

Version 2 (3736.49ms):

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

int main(int argc, char* argv[])
{
    std::chrono::time_point<std::chrono::steady_clock> startTime = std::chrono::steady_clock::now();
    int n = 1000000;
    int m = 1000;

    for (int k = 0; k < m; k++)
    {

        std::vector<int> array;

        array.reserve(n);

        for (int i = 0; i < n - 10; i++)
        {
            array.push_back(i);
        }
    }

    auto time = std::chrono::steady_clock::now() - startTime;
    std::cout   << "Elapsed time: "
            << std::chrono::duration<double, std::milli>(time).count()
            << " ms\n";
    return 0;
}

Can someone please explain to me why such a great difference in the running time? The only difference is in the vector construction. Both are created with size = capacity = 0.

Compiler: g++ 5.4.0 Compiler flags: -Wall -std=c++14 -O2

Damjan Dakic
  • 265
  • 1
  • 19
  • Did you compile with optimizations on? – NathanOliver Feb 01 '17 at 18:41
  • What toolchain, platform, and build commands did you use? – Michael Burr Feb 01 '17 at 18:42
  • Have you verified the loops haven't been optimized out entirely? – jaggedSpire Feb 01 '17 at 18:43
  • I updated the question with the compiler version/flags. Even so, why would optimizations be different between these two sample codes? What is the difference between vector() and vector(0)? – Damjan Dakic Feb 01 '17 at 18:44
  • "What is the difference between vector() and vector(0)?" - different ctor called – Slava Feb 01 '17 at 18:46
  • @Damjan http://en.cppreference.com/w/cpp/container/vector/vector Slava is right, different constructors are indeed called. See ctors 1 and 3 – Nick is tired Feb 01 '17 at 18:53
  • 1
    This seems very compiler specific. gcc 6.3 with -O3 compiles both examples to the same assembly, as does clang 3.9.1 with -O2. – François Andrieux Feb 01 '17 at 18:53
  • Where do you start and stop timing? What exactly are you benchmarking? What methodology are you using? Either way, what you're seeing as a difference is almost certainly just noise. Current versions of both Clang and GCC emit *identical* code for these two snippets in optimized builds. Benchmarks only make sense if you run them *many* times and average the results. – Cody Gray - on strike Feb 01 '17 at 18:54
  • 2
    Do note if you ever want to see the generated assembly you can always use [godbolt](http://gcc.godbolt.org/) – NathanOliver Feb 01 '17 at 18:56
  • 1
    FWIW, libstdc++ tagged at 5.4 shows that the behavior of each constructor is identical (with `0`, it delegates to the default constructor then allocates via `_M_allocate`, which just short-circuits when `n == 0` to do nothing). You'll need to post your actual benchmarking; where does timing start, where does it stop, how many runs, etc. etc., just like Cody suggested. – GManNickG Feb 01 '17 at 19:00
  • 1
    "Both are created with size = capacity = 0" Actually not. Neither vector constructor specifies the capacity. There's already a question about what the initial capacity actually is: http://stackoverflow.com/q/12271017/103167 – Ben Voigt Feb 01 '17 at 19:01
  • I updated the question, it has the exact code I am compiling. The times have changed because I switched a computer, but the behavior is still unchanged. – Damjan Dakic Feb 01 '17 at 19:08
  • Can you compare the assembly listings? – GManNickG Feb 01 '17 at 19:12
  • @GManNickG It's different very much, can't read assembly very well so not sure how to respond :/ – Damjan Dakic Feb 01 '17 at 19:19
  • Btw for you who say that your compiler produces exact assembly, it might be that everything is just optimized out? If that is the case, your test is missing the point - that vector() vs vector(0) causes 2x greater running time. – Damjan Dakic Feb 01 '17 at 19:33
  • What *actually* misses the point is if you are benchmarking code with optimizations disabled. But no, the assembly listings I'm looking at do not have everything optimized out. The compiler is generating code, it's just generating identical code for virtually identical constructs, as you might expect. You can *consistently* get this difference, no matter how many time you run the benchmark? What about if you swap the order in which you do the tests (i.e., do Test 2 first, then Test 1)? – Cody Gray - on strike Feb 02 '17 at 10:16
  • Yes, the results are consistent if I repeat the test and run it in any order. – Damjan Dakic Feb 02 '17 at 13:34
  • Has anyone tested the code on the same compiler with the same flags and confirmed this? – Damjan Dakic Feb 02 '17 at 16:49

0 Answers0