MDman
MDman

Reputation: 526

Performance penalty using 'auto' keyword in Visual Studio 2010

Using the new auto keyword has degraded my code execution times. I narrowed the problem to the following simple code snippet:

#include <iostream>
#include <map>
#include <vector>
#include <deque>
#include <time.h>

using namespace std;

void func1(map<int, vector<deque<float>>>& m)
{
    vector<deque<float>>& v = m[1];
}

void func2(map<int, vector<deque<float>>>& m)
{
    auto v = m[1];
}

void main () {

    map<int, vector<deque<float>>> m;
    m[1].push_back(deque<float>(1000,1));

    clock_t begin=clock();
    for(int i = 0; i < 100000; ++i) func1(m);
    cout << "100000 x func1: " << (((double)(clock() - begin))/CLOCKS_PER_SEC) << " sec." << endl;

    begin=clock();
    for(int i = 0; i < 100000; ++i) func2(m);
    cout << "100000 x func2: " << (((double)(clock() - begin))/CLOCKS_PER_SEC) << " sec." << endl;

}

The output I get on my i7 / Win7 machine (Release mode; VS2010) is:

100000 x func1: 0.001 sec.
100000 x func2: 3.484 sec.

Can anyone explain why using auto results in such a different execution times?

Obviously, there is a simple workaround, i.e., stop using auto altogether, but I hope there is a better way to overcome this issue.

Upvotes: 30

Views: 2595

Answers (2)

Andre
Andre

Reputation: 1607

As Bo said, you have to use auto& instead of auto (Note, that there is also auto* for other cases). Here is an updated version of your code:

#include <functional>
#include <iostream>
#include <map>
#include <vector>
#include <deque>
#include <time.h>

using namespace std;

typedef map<int, vector<deque<float>>> FooType; // this should have a meaningful name

void func1(FooType& m)
{
    vector<deque<float>>& v = m[1];
}

void func2(FooType& m)
{
    auto v = m[1];
}

void func3(FooType& m)
{
    auto& v = m[1];
}

void measure_time(std::function<void(FooType&)> func, FooType& m)
{
    clock_t begin=clock();
    for(int i = 0; i < 100000; ++i) func(m);
    cout << "100000 x func: " << (((double)(clock() - begin))/CLOCKS_PER_SEC) << " sec." << endl;
}

void main()
{
    FooType m;
    m[1].push_back(deque<float>(1000,1));

    measure_time(func1, m);
    measure_time(func2, m);
    measure_time(func3, m);
}

On my computer, it gives the following output:

100000 x func: 0 sec.
100000 x func: 3.136 sec.
100000 x func: 0 sec.

Upvotes: 13

Bo Persson
Bo Persson

Reputation: 92271

You are copying the vector to v.

Try this instead to create a reference

auto& v = ...

Upvotes: 34

Related Questions