简体   繁体   中英

Efficiently erasing elements in tr1::unordered_map

I am experimenting with tr1::unordered_map and stumbled upon the problem how to efficiently delete elements. The 'erase' method offers to delete either by key or by iterator. 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.

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. 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:

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.

I haven't checked whether the tr1 spec has the same guarantee, but it's fairly logical based on the expected implementation.

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. 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 .

Yes, insert() can invalidate all iterators. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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