简体   繁体   English

有效地擦除tr1 :: unordered_map中的元素

[英]Efficiently erasing elements in tr1::unordered_map

I am experimenting with tr1::unordered_map and stumbled upon the problem how to efficiently delete elements. 我正在尝试使用tr1 :: unordered_map,并偶然发现了如何有效删除元素的问题。 The 'erase' method offers to delete either by key or by iterator. 'erase'方法提供了通过键或迭代器删除。 I would assume the latter to be more efficient, since the former presumably involves an implicit find operation. 我认为后者更有效率,因为前者可能涉及隐式查找操作。 On the other hand my investigations on the internet have revealed that iterators may become invalid after calling the insert() method. 另一方面,我在互联网上的调查显示,调用insert()方法后迭代器可能会变得无效。

I am interested in a typical real-world situation, where objects put into a hash table have a life span which is long enough such that calls to insert() happen during that life span. 我对典型的现实世界情况感兴趣,其中放入哈希表的对象具有足够长的寿命,以便在该生命期内发生对insert()的调用。 Thus may I conclude that in such a situation deletion by key is the only option left? 因此,我可以得出结论,在这种情况下,按键删除是唯一的选择吗? Are there any alternatives how to delete objects more efficiently? 有没有其他选择如何更有效地删除对象? I am fully aware that the question only matters in applications, where deletions happen often. 我完全清楚这个问题只在应用程序中很重要,因为删除操作经常发生。 Whether this will be the case for my current project, remains to be seen, but I would rather learn about these issues while designing my project rather than when there is already a lot of code present. 对于我当前的项目是否会出现这种情况还有待观察,但我宁愿在设计项目时了解这些问题,而不是已经存在大量代码。

The whole point of the unordered containers is to have the fastest possible lookup time. 无序容器的重点是尽可能快地查找时间。 Worrying about the time it takes to erase an element by key sounds like the classic example of premature optimization. 担心按键擦除元素所花费的时间就像过早优化的经典例子一样。

If it matters a great deal to you, because you're keeping the iterator for some other reason, then C++0x says of std::unordered_map (quoting from the FDIS), in 23.2.5/11: 如果它对你很重要,因为你因为某些其他原因而保留了迭代器,那么C ++ 0x说的是std::unordered_map (引自FDIS),在23.2.5 / 11中:

The insert and emplace members shall not affect the validity of iterators if (N+n) < z * B, where N is the number of elements in the container prior to the insert operation, n is the number of elements inserted, B is the container's bucket count, and z is the container's maximum load factor. 如果(N + n)<z * B,插入和插入成员不应影响迭代器的有效性,其中N是插入操作之前容器中元素的数量,n是插入的元素数,B是容器的桶数,z是容器的最大负载系数。

I haven't checked whether the tr1 spec has the same guarantee, but it's fairly logical based on the expected implementation. 我没有检查tr1规范是否具有相同的保证,但它基于预期的实现是相当合理的。

If you can use this guarantee, then you can protect your iterators up to a point. 如果您可以使用此保证,那么您可以保护您的迭代器到一定程度。 As Mark says, though, lookup in unordered_map is supposed to be fast. 正如Mark所说, unordered_map查找应该很快。 Keeping a key rather than an iterator is worse than keeping an index rather than an iterator in a vector , but better than the equivalent for map . 保持键而不是迭代器比在vector保留索引而不是迭代器更糟糕,但比map的等价物更好。

Yes, insert() can invalidate all iterators. 是的, insert()可以使所有迭代器无效。 Therefore, I don't think there's a way to avoid the (implicit) lookup. 因此,我认为没有办法避免(隐式)查找。 The good news is that the latter is likely to be cheap. 好消息是后者可能很便宜。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM