I have two different implementation of the same function
IPAddress UMNS::lookup(const HostName& name) const{
auto it=ns.find(name);
if(it!=ns.end()){
return (*it).second;
}
return NON_EXISTING_ADDRESS;
}
and
IPAddress UMNS::lookup(const HostName& name) const{
auto it=find_if(ns.begin(),ns.end(),
[&name] ( const pair<HostName,IPAddress> &a){ return a.first==name;});
bool found = it != ns.end();
if ( found ){
return (*it).second;
}
return NON_EXISTING_ADDRESS;
}
ns is an unordered_map
but execution time of the two functions is not same.
First implementation gives this:
Number of searches: 1000000
Average search time (ms): 0.000373
Second implementation gives this:
Number of searches: 1000000
Average search time (ms): 24.9
Whats wrong with the second implementation?
Why can't I use find_if?
find_if
knows nothing about whether or not the sequence it's searching is a container, let alone whether that container happens to offer an optimised way to do the same task. It will iterate over the sequence it's given, applying the predicate its given, which (for a large container) will be much slower than the hash-based lookup provided by the container's own find
function.
std::find_if
is designed to work with any Input Iterators, which may come from other containers, such as std::vector
. To find an element in generic containers like this, it needs to perform a linear search through all of the elements until it finds the one it's looking for. On the other hand, the find
member of std::unordered_map
is designed specifically for that container and is able to find elements in average constant time.
find_if
必须遍历地图中的每个条目,直到找到您要查找的条目为止,因为它不知道第二个实现与第一个实现等效,因为它无法在您给它的谓词内部看到(并且编译器无法对其进行优化)。
find_if
is the least generic version that doesn't take advantage of the container internal structure or ordering. So it uses plain O(n) search. With the member find
you are getting O(1)
searches, since unordered_map
is implemented as a hash table.
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.