简体   繁体   English

C ++中unordered_map的搜索时间

[英]search time of unordered_map in c++

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. ns是unordered_map但是两个函数的执行时间不同。

First implementation gives this: 第一个实现是这样的:
Number of searches: 1000000 搜索数:1000000
Average search time (ms): 0.000373 平均搜寻时间(毫秒):0.000373

Second implementation gives this: 第二个实现给出了这一点:
Number of searches: 1000000 搜索数:1000000
Average search time (ms): 24.9 平均搜寻时间(毫秒):24.9

Whats wrong with the second implementation? 第二个实施有什么问题?
Why can't I use find_if? 为什么不能使用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. 对于要搜索的序列是否是容器, find_if一无所知,更不用说该容器是否恰巧提供了一种优化的方式来执行相同的任务。 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. 它将使用给定谓词遍历给定的序列,(对于大型容器)将比容器自身的find函数提供的基于哈希的查找慢得多。

std::find_if is designed to work with any Input Iterators, which may come from other containers, such as std::vector . std::find_if旨在与任何输入迭代器一起使用,这些输入迭代器可能来自其他容器,例如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. 另一方面, std::unordered_mapfind成员是专门为该容器设计的,并且能够在平均恒定时间内查找元素。

find_if必须遍历地图中的每个条目,直到找到您要查找的条目为止,因为它不知道第二个实现与第一个实现等效,因为它无法在您给它的谓词内部看到(并且编译器无法对其进行优化)。

find_if is the least generic version that doesn't take advantage of the container internal structure or ordering. find_if是最不通用的版本,它不利用容器的内部结构或顺序。 So it uses plain O(n) search. 因此,它使用普通O(n)搜索。 With the member find you are getting O(1) searches, since unordered_map is implemented as a hash table. 使用成员find您将获得O(1)搜索,因为unordered_map被实现为哈希表。

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

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