我正在调查在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 ++社区的最佳利益。
更新
以下是我所说的这篇调查的论文:
答案 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)
添加了#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
----