简体   繁体   English

使用地图检查ID是否存在

[英]Using a map to check if an id exists

I'm implementing a locking mecahnism and for this I need a fast lookup wether a given Id already is locked. 我正在实现锁定机制,为此,我需要快速查找是否已锁定给定的ID。 Now I was thinking of using a map and I'm wondering if there is some better structure for this. 现在我正在考虑使用地图,我想知道是否有更好的结构。 Basically I don't really need the map, because there is no mapping done. 基本上我真的不需要地图,因为没有完成映射。 However, If I would use a vector, I would have to do a linear search, which would become expensive for many entries. 但是,如果我要使用向量,则必须进行线性搜索,这对于许多条目而言将变得昂贵。

Now I wonder if there is some structure that allows me a similar fast lookup without the additional overhead of storing etra data. 现在,我想知道是否有某种结构可以让我进行类似的快速查找,而又没有存储etra数据的额外开销。

iE

std::map<IdType, bool> locked;

// Prevent deadlock by checking if this thread already locked. Otherwise
// it can pass through.
if(locked.find(Id) != locked.end())
    lock();

As you can see, I don't really need the mapped value. 如您所见,我确实不需要映射值。 I know that for std::vector , using a bool , it is compressed to bits. 我知道对于std::vector ,使用bool其压缩为位。 Now I wonder if I waste a lot of memory for maintaining those bools while I don't even need them anyway. 现在,我想知道我是否浪费了很多内存来维护那些布尔值,而我什至不需要它们。 Would a char be better or some other structure which just gives me the key lookup without the extra data? 一个char会更好还是其他一些结构可以在没有额外数据的情况下为我提供键查询呢?

If you have C++0x, you could use std::unordered_set , average lookup is O(1) . 如果您使用C ++ 0x,则可以使用std::unordered_set ,平均查找为O(1)

From the cppreference.com documentation (emphasis mine): 从cppreference.com文档(重点是我的):

... Search, insertion, and removal have average constant-time complexity . ...搜索,插入和删除的平均恒定时间复杂度

Internally, the elements are not sorted in any particular order, but organized into buckets. 在内部,这些元素不是按任何特定顺序排序的,而是按桶进行组织。 Which bucket an element is placed into depends entirely on the hash of its value. 元素放入哪个存储桶完全取决于其值的哈希值。 This allows fast access to individual elements , since once a hash is computed, it refers to the exact bucket the element is placed into. 这允许快速访问各个元素 ,因为一旦计算了哈希,它就指向元素所放置的确切存储桶。

If you don't have C++0x, unordered_set should be in TR1 : 如果您没有C ++ 0x,则unordered_set应该位于TR1中

#include <tr1/unordered_set>
std::tr1::unordered_set<IdType> locked;

You could also use an unordered_map , but I guess the readers of you code would have a hard time understanding what the mapped value is used for. 您也可以使用unordered_map ,但是我想您的代码读者将很难理解映射值的用途。


PS: And keep the Rules Of Optimization in mind ;) PS:并牢记优化规则 ;)

You can use std::vector<bool> or boost::dynamic_bitset under following conditions: 您可以在以下情况下使用std::vector<bool>boost::dynamic_bitset

  1. IdType is an integral type IdType是整数类型

  2. All id values fit inside a short enough range. 所有id值都在足够短的范围内。 The memory usage will be (length of that range)/8 , which can be a couple of orders of magnitude less than would be consumed by a std::unordered_set<int> or std::set<int> containing all elements from that range. 内存使用量将是(length of that range)/8 ,这可能比包含其中所有元素的std::unordered_set<int>std::set<int>所消耗的内存少几个数量级。范围。

  3. You don't have to iterate over elements of your set (just insert/remove/check presence), or iteration occurs infrequently and the performance emphasis is on insertion/removal/containment-testing operations. 您不必遍历集合中的元素(只需插入/删除/检查状态),或迭代很少发生,并且性能重点在于插入/删除/保持性测试操作。

In such situations a dynamic bitset is a more proper data structure (both faster and more memory efficient). 在这种情况下,动态位集是一种更合适的数据结构(速度更快,存储效率更高)。

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

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