比std :: set更快的查找

时间:2016-02-26 14:35:29

标签: c++ stdset

我需要对某些传统数据包处理代码进行更快的成员资格查找,这需要识别具有特定ID的数据包是否在特定列表中。

该列表仅在数据包匹配非常频繁发生时每隔几秒更新一次,因此查找性能比插入/删除等更重要。

一般流程:

forall(special_PacketIDs)
{
  pktIdSet.insert(theSpecialPktId)
}

while (1)
{
  pkt = readPkt();
  pktID = getPktIdOfPkt(pkt);

  if ( aSpecialPkt(pktID) )
    doSomething();
}

目前,aSpecialPkt(pktId)定义为:

bool PktProcessor::aSpecialPkt(unsigned short pid)
{
  return pktPidSet.find(pid) != pktPidSet.end();
}

gprof报告了在std :: set :: find()

中花费的大量时间

pktId的范围仅为8192个可能的值。以内存为代价分配线性阵列会快得多,例如:

class LinearSet
{
public:
  void insert(pid) { mPktIdSet[pid] = true; }
  bool elementExists(pid)  { return mPktIdSet[pid]; }
private:
  bool mPktIdSet[8192];
}

我的问题是,在保持最佳性能的同时,是否有更多“C ++”方法可以做到这一点?

2 个答案:

答案 0 :(得分:8)

如果您知道正好有8192种可能性,那么您最好的选择可能是std::bitset<8192>,它将使用一千字节,并且非常适合缓存。

答案 1 :(得分:1)

std::bitset<8192>是一个不错的选择,但它实际上取决于您的平台以及特殊数据包ID的数量。请参阅此问题:Choosing between set<int> vs. vector<bool> vs. vector<boolean_t> to use as a bitmap (bitset / bit array)