当我需要修改一个键时,任何避免在std::map中重新分配的方法
Any way to avoid reallocation in std::map when I need to modify a key?
我需要修改std::map
中一个元素的键。
目前,我通过擦除元素并使用不同的键重新插入它来做到这一点。
不幸的是,这是缓慢的——它涉及到额外的堆释放和重新分配。
当我需要修改元素的键时,避免自动节点重新分配和销毁的最好方法是什么?
我认为没有办法避免节点被释放和重新分配。
我能想到的最好的方法是指定一个带有lookaside列表的Allocator,这样当一个节点在被释放后很快被重新分配时,您可以非常快速/轻松地提供相同的节点。
如果您确定键的更改不会影响键的相对顺序,则可以在适当的位置修改键(例如,通过将其指定为可变成员),但这样做会导致未定义的行为——很有可能您可以避开它,但是它仍然是官方未定义的行为。
您至少可以根据您映射的类的内部构造部分进行教训。考虑下面的例子:
class A
{
public:
A(){};
A(int a)
: a_(a)
{
std::cout << "construct" << std::endl;
}
A& operator=(const A& b)
{
a_ = b.a_;
std::cout << "=" << std::endl;
}
A(A&& o)
: a_(o.a_)
{
std::cout << "moved" << std::endl;
}
private:
int a_;
};
有一个move构造函数。通过使用map.emplace
,您可以跳过类成员的重建:
std::map<int, A> mapper;
mapper[1] = A(1);
mapper[2] = A(2);
mapper.emplace(3, std::move(mapper[2]));
mapper.erase(mapper.find(2));
这将打印以下内容:
construct
=
construct
=
moved
表示前两个被构造,但第二个被移动。您仍然需要删除元素,并注意move语义。
如果您的int a_
被替换为一些大的东西,您将通过移动数据和不删除任何内容来减少深度复制时间和删除时间。
这可能会改变您的设计,但可以考虑使用指针(或者更好的是shared_ptr)作为键。这样就可以在不更新键的情况下更新底层数据。
相关文章:
- 存储在 std::map/std::set 中,与在存储所有数据后对向量进行排序
- 如何在<N>不发生内存泄漏的情况下同时(线程安全)填充 c++11 std::map<std::string,std::bitset*>?
- 无法在 std::map<std::string,std::shared_ptr 中设置值<class>>
- 如何在C++中迭代集合映射(std::map<std::set< char>, int >)?
- 如何初始化结构字段 std::map<std::string, std::string>称为参数
- issue with std::map std::find
- 为什么 std::map< std::map >不释放内存?
- C++ map<std::string> vs map<char *> 性能(我知道,"again?" )
- 确定运行时std::map/std::set的内存使用情况
- 映射上的模板参数无效 std::map< std::string, Stock*> &Stock
- 我的SFINAE检查std::map/std::vector有什么问题
- 使用 std::map<std::string, int> 计算表达式树
- 将数据从两种不同的数据结构插入 std::map <std::string, int> mymap 并通过套接字发送
- 类中的编译器错误,数据类型为 typedef map<std::string,std::p air<std::string,vector<int>>> MapPai
- C++ std::map<std::string, std::set<std::string>> .如何循环设置值?
- 如何填写和访问 std::map<std::p air<enum1, enum2>, funcPtr>?
- 二进制'<':找不到 map<std::string shared_ptr 的运算符<Foo>>
- 如何将 2 个字符* 数组直接映射到 std::map<std::string,std::string>
- C++ std::map<std::string, int> 获取键以特定字符串开头的值
- 从取消引用的迭代器返回 std::map<std::string, int> 时出现巨大的内存泄漏