VC++调用STL算法函数有效提升STL列表的搜索速度(附源码)
Posted dvlinker
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了VC++调用STL算法函数有效提升STL列表的搜索速度(附源码)相关的知识,希望对你有一定的参考价值。
STL(Standard Templete Library)活动模板库已被广泛地应用于各种C++程序的开发中,STL中vector、list、map等列表极大地方便了我们日常的开发,不再需要我们去实现链表等数据结构,使用这些列表能基本能解决开发过程中遇到的各种问题。网上关于STL的文章比较多,今天我们就来说说在存放大量数据时我们该如何提升STL列表搜索速度。
1、概述
当vector、list等STL列表中存放的数据量比较大时,去遍历列表去搜索,效率就是个问题了。如果只是简单地使用for循环去遍历STL列表搜索,速度可能会很慢,一般很难达到快速搜索的要求。那有没有什么办法能有效提升STL的搜索速度呢?答案是肯定的,可以调用STL库的算法函数去进行STL列表的搜索,能够明显提升STL列表的搜索速度。STL库自带的算法函数有conut、count_if、find、find_if、remove_copy、remove_copy_if等。这些STL算法函数的详细说明可以参见《STL源码剖析》一书的第6章。
本文将详细讲述使用STL算法函数find_if和remove_copy_if有效提升搜索速度的范例,给大家提供一个参考。
2、使用find_if搜索单个元素
有时我们需要通过一个id关键字段到STL列表中搜索对应元素的信息。假设有如下设备信息结构体TDeviceInfo,存放整个设备列表信息的是vector列表vtDevList:
// 设备信息
struct TDeviceInfo
char* achDeviceId[64]; // 设备id
char* achDeviceName[64]; // 设备名称
int nDevType; // 设备类型
;
vector<TDeviceInfo> vtDevList; // 存放设备信息的列表
我们由设备id去到vector列表中找对应的设备信息。直接通过for循环去遍历搜索的代码如下:
char* pTargetId = "E40CF3E4-CC2B-437F-A4B9-65F2D5BD0712";
// 通过for循环去遍历列表搜目标设备
vector<TDeviceInfo>::iterator itor = vtDevList.begin();
for ( ; itor != vtDevList.end(); itor++ )
if ( strcmp(pTargetId, itor->achDeviceId) == 0 )
// 找到目标设备
break;
上述代码通过设备id去找对应的设备信息,是单个设备信息。
我们可以使用find_if算法函数对上述代码进行改进,代码如下:
char* pTarget = "E40CF3E4-CC2B-437F-A4B9-65F2D5BD0712";
vector<TDeviceInfo>::iterator itor = std::find_if(vtDevList.begin(), vtDevList.end(),
[&](TDeviceInfo tInfo) return strcmp(pTarget, tInfo.achDeviceId)==0; );
if (itor != vtDevList.end())
// 找到目标设备
使用find_if算法函数可以明显提升搜索的速度。此外,上述函数中使用了C++11中的匿名函数,匿名函数是个好东西,很好用!
3、使用remove_copy_if搜索满足搜索条件的多个元素
我们有时需要到STL列表去搜索满足搜索条件的多个元素。比如我们要到设备列表中去搜索所有包含“东城区”字样的所有设备信息,使用for循环去遍历的代码如下:
// 通过for循环去遍历列表搜目标设备
char* pMatchNameStr = "东城区";
vector<TDeviceInfo> vtMatchedDevList; // 存放满足匹配条件的元素
vector<TDeviceInfo>::iterator itor = vtDevList.begin();
for (; itor != vtDevList.end(); itor++)
CStringA strDeviceName = itor->achDeviceName;
if (strDeviceName.Find(strDeviceName) != -1)
vtMatchedDevList.push_back(*itor);
当设备列表vtDevList中存放了数万个元素时,上述for循环搜索的效率就不太高了,我们可以通过使用remove_copy_if算法函数去对现有代码进行替换:
BOOL MatchDeviceFunc(TDeviceInfo& tInfo)
char* pMatchNameStr = "东城区";
CStringA strDeviceName = tInfo.achDeviceName;
if ( strDeviceName.Find(pMatchNameStr) != -1 )
return TRUE;
return FALSE;
vector<TDeviceInfo> vtMatchedDevList;
std::remove_copy_if(vtDevList.begin(), vtDevList.end(), std::back_inserter(vtMatchedDevList), &MatchDeviceFunc);
对于上述remove_copy_if调用,前两个参数指明搜索开始和结束的迭代器,第三个元素指定存放满足搜索条件的元素的列表,第四个参数指定条件判断函数MatchDeviceFunc。
remove_copy_if算法函数的调用,可以有效地提升搜索速度。在我们项目中做过类似这样的优化,搜索速度可以提升1到2个数量级。
4、总结
在我们搜索STL列表速度遇到瓶颈时,可以考虑使用STL自带的算法函数去有效提升搜索效率。其实我们以前对比过STL算法函数内部的实现,很多STL算法函数内部实现和我们直接去通过for循环遍历的代码是类似的,甚至是一模一样的,比如find_if算法函数的实现,那为啥使用算法函数时就是要快很多呢?可能是编译器能对算法函数中的代码进行更好的优化,使其在运行时能跑的更快一点。
以上是关于VC++调用STL算法函数有效提升STL列表的搜索速度(附源码)的主要内容,如果未能解决你的问题,请参考以下文章