如何解决std :: map :: operator []比std :: map :: insert更有效?
我了解到 operator [] 等同于
(*((this->insert(make_pair(k,mapped_type()))).first)).second
因此,如果地图中不存在键,则使用 operator [] 的效率要比使用 insert 的效率低,对吧?因为还有一个步骤,所以使用默认构造。
所以我写了一个演示来测试,像这样。
#include <iostream>
#include <map>
using namespace std;
static int id = 0;
class Foo
{
public:
Foo()
: _val(0)
{
_id = ++id;
cout << _id << " construct_no_param:" << _val << endl;
}
Foo(int val)
: _val(val)
{
_id = ++id;
cout << _id << " construct_has_param:" << _val << endl;
}
Foo(Foo &rhs)
: _val(rhs._val)
{
_id = ++id;
cout << _id << " construct_copy:" << _val << endl;
}
Foo(const Foo &rhs)
: _val(rhs._val)
{
_id = ++id;
cout << _id << " construct_const_copy:" << _val << endl;
}
Foo &operator=(Foo &rhs)
{
_val = rhs._val;
cout << _id << " assign:" << _val << endl;
}
Foo &operator=(const Foo &rhs)
{
_val = rhs._val;
cout << _id << " const_assign:" << _val << endl;
}
~Foo()
{
cout << _id << " destruct:" << _val << endl;
}
int _val;
int _id;
};
int main() {
map<int,Foo> m;
const Foo f(2);
cout << "-----" << endl;
// m[1] = f;
// m.insert(make_pair(1,f));
cout << "-----" << endl;
return 0;
}
首先,我使用了 operator []
m[1] = f;
我明白了:
1 construct_has_param:2
-----
2 construct_no_param:0
3 construct_const_copy:0
4 construct_const_copy:0
3 destruct:0
2 destruct:0
4 assign:2
-----
1 destruct:2
4 destruct:2
然后,我使用了插入
m.insert(make_pair(1,f));
我明白了:
1 construct_has_param:2
-----
2 construct_const_copy:2
3 construct_const_copy:2
4 construct_const_copy:2
5 construct_const_copy:2
4 destruct:2
3 destruct:2
2 destruct:2
-----
1 destruct:2
5 destruct:2
结果与我预期的不符。为什么insert
有更多的构造?这是怎么回事?
顺便说一句,我使用-O0选项禁用优化,但是我不确定它是否有效。
gcc版本4.8.2 20131212(Red Hat 4.8.2-8)(GCC)
解决方法
表达式make_pair(1,f)
的类型为std::pair<int,Foo>
,它不是您的地图value_type
,它是std::pair<const int,Foo>
,因此{{1 }}。然后insert
中有2个副本,如果您所有的特殊成员都没有抑制移动结构的生成,那将是移动。
如果要避免复制,请使用emplace
map
并定义m.emplace(1,f);
的移动构造函数和赋值
Foo
我还建议删除非const复制操作。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。