[zeromq-dev] STL use in zeromq
Mikael Helbo Kjær
mhk at designtech.dk
Fri Oct 29 11:58:37 CEST 2010
Hi all
I was looking through the source code and I wondered if there is a specific reason for something I observed. 0mq uses std::vector in several places often typedef'ed or in through yarray.hpp. And that is just fine, but often when values are removed they're removed one at a time during an iteration across the vector (which as far as I know and feel free to correct me) is the slowest way to remove values from a std::vector. I've been taught to use the Erase-Remove idiom, but maybe the call overhead is higher than I think or there is another reason. For example the following code from ctx.cpp:
void zmq::ctx_t::unregister_endpoints (socket_base_t *socket_)
{
endpoints_sync.lock ();
endpoints_t::iterator it = endpoints.begin ();
while (it != endpoints.end ()) {
if (it->second == socket_) {
endpoints_t::iterator to_erase = it;
it++;
endpoints.erase (to_erase);
continue;
}
it++;
}
endpoints_sync.unlock ();
}
Could be rewritten to (not tested just done off the top of my head, and this is one of the more complex examples really):
struct IsSocket
{
socket_base_t *socket_;
bool operator()(std::pair<std::string, socket_base_t> value)
{
return (value->second == socket_);
}
};
void zmq::ctx_t::unregister_endpoints (socket_base_t *socket_)
{
endpoints_sync.lock ();
IsSocket is;
Is.socket_ = socket_;
endpoints.erase(std::remove_if(endpoints.begin(), endpoints.end(), is), endpoints.end());
endpoints_sync.unlock ();
}
The idea here is to swap/move the elements that are to be deleted to the end and then only remove them in one remove operation (which vector implementers could easily have optimized in case the second element of the erase call is end).
But I might be wrong and so I ask if something like this has been considered during the 0mq implementation, because the STL use seems rather dedicatedly different here.
Regards,
Mikael
More information about the zeromq-dev
mailing list