在Visual Studio 2010中使用'auto'关键字会导致性能惩罚

30

使用新的auto关键字会降低我的代码执行时间。我将问题缩小到以下简单的代码片段:

#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;

}

我在我的i7 / Win7机器上运行(发布模式; VS2010),得到的输出是:

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

有人能解释一下为什么使用auto会导致如此不同的执行时间吗?

显然,有一个简单的解决方法,即停止完全使用auto,但我希望有更好的方法来解决这个问题。

2个回答

34
你正在复制向量到 v。尝试使用以下方法创建一个引用代替。
auto& v = ...

1
该死,你必须非常快才能回答那些问题。;-) - Andre
我曾认为(但我想我错了),auto使用函数的返回类型。operator[]的返回类型是引用,那么为什么我们需要添加额外的'&'呢? - MDman
12
auto 关键字会移除顶层的常数限定符和引用类型,它会让推导出来的类型 "衰变"。 - Xeo
5
@MDman: 另外,如果推导类型始终与表达式的类型完全相同,那么您将如何能够创建副本呢? :) 我认为这是让 auto 以这种方式运行的原因之一。 - Xeo

13

正如 Bo 所说,您必须使用 auto& 而不是 auto(请注意,还有其他情况下的 auto*)。这是您代码的更新版本:

#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);
}

在我的电脑上,它会输出以下内容:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接