zoukankan      html  css  js  c++  java
  • 使用unordered_map提升查找效率

     

    在对网络数据包流(Flow)进行处理的时候,一开始为了简单使用了vector做为Flow信息的存储容器,当其中的元素达到几十万时,程序的执行速度让人无法忍受。已经对vector进行过合理的预先reserve,因为不是push_back的问题,而是查找。后改为unordered_map,对于同样的数据,执行时间从3分40秒提高到10秒。

    unordered_map应该是一个C++11特性,较旧的编译器应该不支持。而VC++2012文档中也提到废弃了hash_map,而使用unordered_map。相关参考见http://www.cplusplus.com/reference/unordered_map/unordered_map

    以下是代码。

    先编写键结构,这里用的是俗称的“五元组”:

    struct flow_key
    {
        int32   ipa;
        int32   ipb;
        uint16  porta;
        uint16  portb;
        uint32  proto;
    
        friend bool operator== (const flow_key& a, const flow_key& b);
    };

      因为flow_key是自定义的键类型,因此除了上面的operator==,还需要实现hash函数,这里我是随便写的一个,发生冲突的机会应该相当高了,呵呵。据资料说,当hash函数结果相同时,则继续调用operator==进行比较:

    struct flow_hash
    {
        size_t operator() (const flow_key& k) const
        {
            return k.ipa + k.ipb + k.porta + k.portb;
        }
    };

      接下来编写value结构,我用的是flow_info,代码较多,就不贴了。

    为了之后减小代码敲入字数,我给以上述2者为key和value的unordered_map起了个别名:

    typedef std::unordered_map<flow_key,  flow_info,  flow_hash>        flow_map_t;

    我这里都用的值类型,没用指针类型,也许能再快些,但指针带来的烦恼也是有代价的,呵呵。

    在使用此类型的地方,做如下声明:

    flow_map_t  m_flows;

    OK了,可以用了。

    在使用的过程中,如果要查找,代码大概如下:

            pair<flow_map_t::iterator, bool> hash_ret;
            flow_map_t::iterator it = m_flows.find(fkey);
    
            if(it == m_flows.end())
            {
                // 没找到,插入新项
                hash_ret = m_flows.insert(make_pair(fkey, flow));
                it = hash_ret.first;
            }

    注意insert操作的返回类型哦,是一个pair,first是插入的对应的迭代器,second是bool值,指示插入是否成功。

    我这里主要是还要进行一些额外操作,所以用了什么find之类,如果你不关心这个键是否已在map之中,只想没有就插入,那直接进行insert操作就可以了,如果已经存在此键,则hash_ret的first就是已存在键的元素所对应的迭代器。

    由于我需要以整数下标对流信息进行各种操作,所以我在得到完整的unordered_map之后,把它复制给了vector。

  • 相关阅读:
    信息收集与扫描
    流密码
    信息安全面临的威胁
    .net core Web应用启动类
    .net core 1.0 Web MVC 自定义认证过程
    彻底脱离循环与结束当下循环
    Java多线程:Thread中的实例方法
    memcached安装问题
    五月的仓颉
    json时间格式化方法
  • 原文地址:https://www.cnblogs.com/zzqcn/p/3157764.html
Copyright © 2011-2022 走看看