有关插入和安装的VC ++请求调查

时间:2014-07-24 04:12:55

标签: visual-c++ c++11

我正在调查在vector的以下成员函数中执行了多少特殊成员函数:

insert
emplace
push_back
emplace_back

在各种运行时间条件下。我的目的是发表一篇文章,将这些成员函数相互比较,并在std :: lib:libstdc ++,libc ++和vc ++的每个c ++ 11实现上进行比较,并提供关于何时最好的建议。使用每个成员函数(当可能有多个选项时)。我有关于libc ++和libstdc ++ - 4.8的数据,但我缺少关于vc ++的数据。

我正在寻找vc ++的答案,其中包括vc ++版本号(2010,2012,2013)。我的目的是就何时应该优先考虑这些成员的时间提供建议,并通过实际经验进行调整。我将对每个vc ++版本的第一个响应进行投票。我的意图不是打击任何特定的平台。但是,如果我的结果鼓励任何现有平台在未来得到改善,那么那就是肉汁了。

我希望看到测试的结果是:

#include <iostream>
#include <vector>

class X
{
    int i_;
    int* p_;

public:
    struct special
    {
        unsigned c;
        unsigned dt;
        unsigned cc;
        unsigned ca;
        unsigned mc;
        unsigned ma;
    };
    static special sp;

    X(int i, int* p)
        : i_(i)
        , p_(p)
    {
//         std::cout << "X(int i, int* p)\n";
        sp.c++;
    }

    ~X()
    {
//         std::cout << "~X()\n";
        sp.dt++;
    }

    X(const X& x)
        : i_(x.i_)
        , p_(x.p_)
    {
//         std::cout << "X(const X& x)\n";
        sp.cc++;
    }

    X& operator=(const X& x)
    {

        i_ = x.i_;
        p_ = x.p_;
//         std::cout << "X& operator=(const X& x)\n";
        sp.ca++;
        return *this;
    }

    X(X&& x) noexcept
        : i_(x.i_)
        , p_(x.p_)
    {
//         std::cout << "X(X&& x)\n";
        sp.mc++;
    }

    X& operator=(X&& x) noexcept
    {

        i_ = x.i_;
        p_ = x.p_;
//         std::cout << "X& operator=(X&& x)\n";
        sp.ma++;
        return *this;
    }

};

std::ostream&
operator<<(std::ostream& os, X::special const& sp)
{
    os << sp.c << '\n';
    os << sp.dt << '\n';
    os << sp.cc << '\n';
    os << sp.ca << '\n';
    os << sp.mc << '\n';
    os << sp.ma << '\n';
    return os;
}

X::special X::sp{};

int
main()
{
    {
        std::vector<X> v;
        v.reserve(4);
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        X x{0,0};
        std::cout << "--insert lvalue no reallocation--\n";
        X::sp = {};
        v.insert(v.begin(), x);
        std::cout << X::sp;
        std::cout << "----\n";
    }
    {
        std::vector<X> v;
        v.reserve(4);
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        X x{0,0};
        std::cout << "--emplace lvalue no reallocation--\n";
        X::sp = {};
        v.emplace(v.begin(), x);
        std::cout << X::sp;
        std::cout << "----\n";
    }
    {
        std::vector<X> v;
        v.reserve(4);
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        X x{0,0};
        std::cout << "--insert xvalue no reallocation--\n";
        X::sp = {};
        v.insert(v.begin(), std::move(x));
        std::cout << X::sp;
        std::cout << "----\n";
    }
    {
        std::vector<X> v;
        v.reserve(4);
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        X x{0,0};
        std::cout << "--emplace xvalue no reallocation--\n";
        X::sp = {};
        v.emplace(v.begin(), std::move(x));
        std::cout << X::sp;
        std::cout << "----\n";
    }
    {
        std::vector<X> v;
        v.reserve(4);
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        std::cout << "--insert rvalue no reallocation--\n";
        X::sp = {};
        v.insert(v.begin(), X{0,0});
        std::cout << X::sp;
        std::cout << "----\n";
    }
    {
        std::vector<X> v;
        v.reserve(4);
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        std::cout << "--emplace rvalue no reallocation--\n";
        X::sp = {};
        v.emplace(v.begin(), X{0,0});
        std::cout << X::sp;
        std::cout << "----\n";
    }
    {
        std::vector<X> v;
        v.reserve(3);
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        X x{0,0};
        std::cout << "--insert lvalue reallocation--\n";
        X::sp = {};
        v.insert(v.begin(), x);
        std::cout << X::sp;
        std::cout << "----\n";
    }
    {
        std::vector<X> v;
        v.reserve(3);
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        X x{0,0};
        std::cout << "--emplace lvalue reallocation--\n";
        X::sp = {};
        v.emplace(v.begin(), x);
        std::cout << X::sp;
        std::cout << "----\n";
    }
    {
        std::vector<X> v;
        v.reserve(3);
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        X x{0,0};
        std::cout << "--insert xvalue reallocation--\n";
        X::sp = {};
        v.insert(v.begin(), std::move(x));
        std::cout << X::sp;
        std::cout << "----\n";
    }
    {
        std::vector<X> v;
        v.reserve(3);
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        X x{0,0};
        std::cout << "--emplace xvalue reallocation--\n";
        X::sp = {};
        v.emplace(v.begin(), std::move(x));
        std::cout << X::sp;
        std::cout << "----\n";
    }
    {
        std::vector<X> v;
        v.reserve(3);
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        std::cout << "--insert rvalue reallocation--\n";
        X::sp = {};
        v.insert(v.begin(), X{0,0});
        std::cout << X::sp;
        std::cout << "----\n";
    }
    {
        std::vector<X> v;
        v.reserve(3);
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        std::cout << "--emplace rvalue reallocation--\n";
        X::sp = {};
        v.emplace(v.begin(), X{0,0});
        std::cout << X::sp;
        std::cout << "----\n";
    }

    {
        std::vector<X> v;
        v.reserve(4);
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        X x{0,0};
        std::cout << "--push_back lvalue no reallocation--\n";
        X::sp = {};
        v.push_back(x);
        std::cout << X::sp;
        std::cout << "----\n";
    }
    {
        std::vector<X> v;
        v.reserve(4);
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        X x{0,0};
        std::cout << "--emplace_back lvalue no reallocation--\n";
        X::sp = {};
        v.emplace_back(x);
        std::cout << X::sp;
        std::cout << "----\n";
    }
    {
        std::vector<X> v;
        v.reserve(4);
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        X x{0,0};
        std::cout << "--push_back xvalue no reallocation--\n";
        X::sp = {};
        v.push_back(std::move(x));
        std::cout << X::sp;
        std::cout << "----\n";
    }
    {
        std::vector<X> v;
        v.reserve(4);
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        X x{0,0};
        std::cout << "--emplace_back xvalue no reallocation--\n";
        X::sp = {};
        v.emplace_back(std::move(x));
        std::cout << X::sp;
        std::cout << "----\n";
    }
    {
        std::vector<X> v;
        v.reserve(4);
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        std::cout << "--push_back rvalue no reallocation--\n";
        X::sp = {};
        v.push_back(X{0,0});
        std::cout << X::sp;
        std::cout << "----\n";
    }
    {
        std::vector<X> v;
        v.reserve(4);
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        std::cout << "--emplace_back rvalue no reallocation--\n";
        X::sp = {};
        v.emplace_back(X{0,0});
        std::cout << X::sp;
        std::cout << "----\n";
    }
    {
        std::vector<X> v;
        v.reserve(3);
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        X x{0,0};
        std::cout << "--push_back lvalue reallocation--\n";
        X::sp = {};
        v.push_back(x);
        std::cout << X::sp;
        std::cout << "----\n";
    }
    {
        std::vector<X> v;
        v.reserve(3);
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        X x{0,0};
        std::cout << "--emplace_back lvalue reallocation--\n";
        X::sp = {};
        v.emplace_back(x);
        std::cout << X::sp;
        std::cout << "----\n";
    }
    {
        std::vector<X> v;
        v.reserve(3);
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        X x{0,0};
        std::cout << "--push_back xvalue reallocation--\n";
        X::sp = {};
        v.push_back(std::move(x));
        std::cout << X::sp;
        std::cout << "----\n";
    }
    {
        std::vector<X> v;
        v.reserve(3);
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        X x{0,0};
        std::cout << "--emplace_back xvalue reallocation--\n";
        X::sp = {};
        v.emplace_back(std::move(x));
        std::cout << X::sp;
        std::cout << "----\n";
    }
    {
        std::vector<X> v;
        v.reserve(3);
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        std::cout << "--push_back rvalue reallocation--\n";
        X::sp = {};
        v.push_back(X{0,0});
        std::cout << X::sp;
        std::cout << "----\n";
    }
    {
        std::vector<X> v;
        v.reserve(3);
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        v.push_back(X(0,0));
        std::cout << "--emplace_back rvalue reallocation--\n";
        X::sp = {};
        v.emplace_back(X{0,0});
        std::cout << X::sp;
        std::cout << "----\n";
    }
}

例如,以下是gcc-4.8上的此测试的输出:https://ideone.com/imAMnU

如果有人发现4.8之后的gcc版本的结果不同并且想要提供这些结果,那么也会受到赞赏(并且赞成)。如果我无法区分哪些等效响应首先出现,我很乐意对所有这些响应进行投票。但是目前我不确定如何为这次调查选择正确答案。

我可能会在任何可能发布的内容中感谢数据的贡献者。我也很高兴在这个问题中发布一个链接,以便将来可能从这些数据中得出任何结论。

总之,我意识到这种问题不是SO的标准。然而,它是本着在C ++社区中进一步提高公众知识的精神,并且尽可能透明地管理我们。如果人们出于某种原因想要关闭这个问题,我接受这个问题,但个人认为这不符合C ++社区的最佳利益。

更新

以下是我所说的这篇调查的论文:

  

insert vs emplace

3 个答案:

答案 0 :(得分:5)

使用发布模式编译的VS2012代码。

命令

cl / O2 / EHsc / W4 Console_12.cpp

<强>输出

--insert lvalue no reallocation--    
4        
4        
1        
3        
4  
0           
----    
--emplace lvalue no reallocation--    
8    
15    
2    
3    
10    
6    
----    
--insert xvalue no reallocation--    
12    
26    
2    
3    
17    
12    
----    
--emplace xvalue no reallocation--    
16    
37    
2    
3    
24    
18    
----    
--insert rvalue no reallocation--    
20    
49    
2    
3    
31    
24    
----    
--emplace rvalue no reallocation--    
24    
60    
2    
3    
38    
30    
----    
--insert lvalue reallocation--    
28    
70    
3    
3    
44    
30    
----    
--emplace lvalue reallocation--    
32    
84    
4    
3    
53    
36    
----    
--insert xvalue reallocation--    
36    
98    
4    
3    
63    
42    
----    
--emplace xvalue reallocation--    
40    
112    
4    
3    
73    
48    
----    
--insert rvalue reallocation--    
44    
127    
4    
3    
83    
54    
----    
--emplace rvalue reallocation--    
48    
141    
4    
3    
93    
60    
----    
--push_back lvalue no reallocation--    
52    
148    
5    
3    
96    
60    
----    
--emplace_back lvalue no reallocation--    
56    
156    
6    
3    
99    
60    
----    
--push_back xvalue no reallocation--    
60    
164    
6    
3    
103    
60    
----    
--emplace_back xvalue no reallocation--    
64    
172    
6    
3    
107    
60    
----    
--push_back rvalue no reallocation--    
68    
181    
6    
3    
111    
60    
----    
--emplace_back rvalue no reallocation--    
72    
189    
6    
3    
115    
60    
----    
--push_back lvalue reallocation--    
76    
199    
7    
3    
121    
60    
----    
--emplace_back lvalue reallocation--    
80    
210    
8    
3    
127    
60    
----    
--push_back xvalue reallocation--    
84    
221    
8    
3    
134    
60    
----    
--emplace_back xvalue reallocation--    
88    
232    
8    
3    
141    
60    
----    
--push_back rvalue reallocation--    
92    
244    
8    
3    
148    
60    
----    
--emplace_back rvalue reallocation--    
96    
255    
8    
3    
155    
60    
----    

答案 1 :(得分:4)

VS2013

添加了#define noexcept,我认为这也将在VS2010和2012案例中完成。

发布结果:

/GS /GL /analyze- /W3 /Gy /Zc:wchar_t /Zi /Gm- /O2 /sdl /Fd"Release\vc120.pdb" /fp:precise /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_LIB" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /Gd /Oy- /Oi /MD /Fa"Release\" /EHsc /nologo /Fo"Release\" /Fp"Release\Howard.pch" 

--insert lvalue no reallocation--
0
1
1
3
1
0
----
--emplace lvalue no reallocation--
0
3
1
0
3
6
----
--insert xvalue no reallocation--
0
3
0
0
4
6
----
--emplace xvalue no reallocation--
0
3
0
0
4
6
----
--insert rvalue no reallocation--
1
4
0
0
4
6
----
--emplace rvalue no reallocation--
1
4
0
0
4
6
----
--insert lvalue reallocation--
0
3
1
0
3
0
----
--emplace lvalue reallocation--
0
6
1
0
6
6
----
--insert xvalue reallocation--
0
6
0
0
7
6
----
--emplace xvalue reallocation--
0
6
0
0
7
6
----
--insert rvalue reallocation--
1
7
0
0
7
6
----
--emplace rvalue reallocation--
1
7
0
0
7
6
----
--push_back lvalue no reallocation
0
0
1
0
0
0
----
--emplace_back lvalue no reallocat
0
0
1
0
0
0
----
--push_back xvalue no reallocation
0
0
0
0
1
0
----
--emplace_back xvalue no reallocat
0
0
0
0
1
0
----
--push_back rvalue no reallocation
1
1
0
0
1
0
----
--emplace_back rvalue no reallocat
1
1
0
0
1
0
----
--push_back lvalue reallocation--
0
3
1
0
3
0
----
--emplace_back lvalue reallocation
0
3
1
0
3
0
----
--push_back xvalue reallocation--
0
3
0
0
4
0
----
--emplace_back xvalue reallocation
0
3
0
0
4
0
----
--push_back rvalue reallocation--
1
4
0
0
4
0
----
--emplace_back rvalue reallocation
1
4
0
0
4
0
----

调试结果:

/GS /analyze- /W3 /Zc:wchar_t /ZI /Gm /Od /sdl /Fd"Debug\vc120.pdb" /fp:precise /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_LIB" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /Oy- /MDd /Fa"Debug\" /EHsc /nologo /Fo"Debug\" 

--insert lvalue no reallocation--
0
1
1
3
1
0
----
--emplace lvalue no reallocation-
0
3
1
0
3
6
----
--insert xvalue no reallocation--
0
3
0
0
4
6
----
--emplace xvalue no reallocation-
0
3
0
0
4
6
----
--insert rvalue no reallocation--
1
4
0
0
4
6
----
--emplace rvalue no reallocation-
1
4
0
0
4
6
----
--insert lvalue reallocation--
0
3
1
0
3
0
----
--emplace lvalue reallocation--
0
6
1
0
6
6
----
--insert xvalue reallocation--
0
6
0
0
7
6
----
--emplace xvalue reallocation--
0
6
0
0
7
6
----
--insert rvalue reallocation--
1
7
0
0
7
6
----
--emplace rvalue reallocation--
1
7
0
0
7
6
----
--push_back lvalue no reallocatio
0
0
1
0
0
0
----
--emplace_back lvalue no realloca
0
0
1
0
0
0
----
--push_back xvalue no reallocatio
0
0
0
0
1
0
----
--emplace_back xvalue no realloca
0
0
0
0
1
0
----
--push_back rvalue no reallocatio
1
1
0
0
1
0
----
--emplace_back rvalue no realloca
1
1
0
0
1
0
----
--push_back lvalue reallocation--
0
3
1
0
3
0
----
--emplace_back lvalue reallocatio
0
3
1
0
3
0
----
--push_back xvalue reallocation--
0
3
0
0
4
0
----
--emplace_back xvalue reallocatio
0
3
0
0
4
0
----
--push_back rvalue reallocation--
1
4
0
0
4
0
----
--emplace_back rvalue reallocatio
1
4
0
0
4
0
----

答案 2 :(得分:3)

使用发布模式编译VS2010代码。

命令

cl / O2 / EHsc / W4 EmplaceTest.cpp

<强>输出

--insert lvalue no reallocation--
4
6
1
0
6
6
----
--emplace lvalue no reallocation--
8
17
2
0
12
12
----
--insert xvalue no reallocation--
12
28
2
0
19
18
----
--emplace xvalue no reallocation--
16
39
2
0
26
24
----
--insert rvalue no reallocation--
20
51
2
0
33
30
----
--emplace rvalue no reallocation--
24
62
2
0
40
36
----
--insert lvalue reallocation--
28
75
3
0
49
42
----
--emplace lvalue reallocation--
32
89
4
0
58
48
----
--insert xvalue reallocation--
36
103
4
0
68
54
----
--emplace xvalue reallocation--
40
117
4
0
78
60
----
--insert rvalue reallocation--
44
132
4
0
88
66
----
--emplace rvalue reallocation--
48
146
4
0
98
72
----
--push_back lvalue no reallocation--
52
153
5
0
101
72
----
--emplace_back lvalue no reallocation--
56
161
6
0
104
72
----
--push_back xvalue no reallocation--
60
169
6
0
108
72
----
--emplace_back xvalue no reallocation--
64
177
6
0
112
72
----
--push_back rvalue no reallocation--
68
186
6
0
116
72
----
--emplace_back rvalue no reallocation--
72
194
6
0
120
72
----
--push_back lvalue reallocation--
76
204
7
0
126
72
----
--emplace_back lvalue reallocation--
80
215
8
0
132
72
----
--push_back xvalue reallocation--
84
226
8
0
139
72
----
--emplace_back xvalue reallocation--
88
237
8
0
146
72
----
--push_back rvalue reallocation--
92
249
8
0
153
72
----
--emplace_back rvalue reallocation--
96
260
8
0
160
72
----