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