Samo Jordan
Samo Jordan

Reputation: 41

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.

Upvotes: 4

Views: 2488

Answers (3)

Steve Jessop
Steve Jessop

Reputation: 279245

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.

Upvotes: 2

Mark Ransom
Mark Ransom

Reputation: 308120

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.

Upvotes: 5

NPE
NPE

Reputation: 500257

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.

Upvotes: 1

Related Questions