C++ 比std::set更快的查找速度

C++ 比std::set更快的查找速度,c++,stdset,C++,Stdset,我需要对一些遗留数据包处理代码进行更快的成员查找,这些代码需要识别具有特定ID的数据包是否在特定列表中 列表仅每隔几秒钟更新一次,而数据包匹配非常频繁,因此查找性能比插入/删除等更重要 一般流程: forall(special_PacketIDs) { pktIdSet.insert(theSpecialPktId) } while (1) { pkt = readPkt(); pktID = getPktIdOfPkt(pkt); if ( aSpecialPkt(pktI

我需要对一些遗留数据包处理代码进行更快的成员查找,这些代码需要识别具有特定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++”的方法来实现这一点,同时保持最佳性能?

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

std::bitset
是一个不错的选择,但这实际上取决于您的平台以及特殊数据包ID的数量。查看此问题:

您是否尝试了
std::unordered\u set
或只是
std::vector
?现在该集合被定义为std::set。但是无序_集似乎只在C++11中可用,如果没有大量工作,这段旧代码将无法工作。@Danny:查找std::set的复杂性是对数的,而查找std::无序_集的平均常数(最坏情况下是线性的)@DieterLück你是对的。我想我应该停止在这里张贴愚蠢的东西……我删除了我的评论。很好的选择。只是补充一点,作为将来的参考,如果尺寸要大得多,并且一些错误是可以的,那么a可能是合适的。这很完美。谢谢@AmiTavory非常好的建议-难以捉摸的bloom过滤器的一个很好的使用案例。:)太好了。谢谢