高效使用STL

1、当对象很大时,建立指针的容器而不是对象的容器

注意事项: 
  1)容器销毁前需要自行销毁指针所指向的对象;否则就造成了内存泄漏;
  2)使用排序等算法时需要构造基于对象的比较函数,如果使用默认的比较函数,其结果是基于指针大小的比较,而不是对象的比较;
二、用empty() 代替size()来检查是否为空
因为对于list,size()会遍历每一个元素来确定大小,时间复杂度 o(n),线性时间;empty总是保证常数时间; 
 
三、尽量用区间成员函数代替单元素操作
使用区间成员函数有以下好处:1)更少的函数调用; 2)更少的元素移动; 3)更少的内存分配
例:将v2后半部的元素赋值给v1:
单元式操作:
for (vector::const_iterator ci = v2.begin() + v2.size() / 2; ci != v2.end(); ++ci)
  v1.push_back(*ci)
使用区间成员函数assign(): 
v1.assign(v2.begin() + v2.size() / 2, v2.end());
 四、使用reserver避免不必要的内存分配(for vector)
如果预先知道空间的大小,预先分配了空间避免了重新分配空间和复制的代价 
注:reserve()只是修改了容量,并非大小,向vector中增加元素还是需要通过push_back加入; 
 
五、使用有序的vector代替关联容器(阶段性的操作适用)
对阶段性操作的定义: 先做一系列插入、完成之后,后续操作都是查询; 在阶段性的操作下,使用vector有以下优势: 
  1)因为vector有序,关联容器带来的有序优势散失;
  2)都是使用二分法查找的前提下,查询算法对连续的内存空间的访问要快于离散的空间;
六、在map的insert()和operator[]中仔细选择
插入时,insert效率高;因为operator会先探查是否存在这个元素,如果不存在就构造一个临时的,然后才涉及到赋值,多了一个临时对象的构造; 更新时,[]效率更高insert会创造一个对象,然后覆盖一个原有对象;而[]是在原有的对象上直接赋值操作; 
散列函数的默认比较函数是equal_to,因为不需要保持有序;
 

 注: 用insert不能更改原数据、而用[ ]则可以

 

七、尽量用算法替代手写的循环

八、尽量用成员函数代替同名的算法

1)基于效率考虑,成员函数知道自己这个容器和其他容器有哪些特有属性,能够利用到这些特性;而通用算法不可以; 
2)对于关联容器,成员函数find基于等价搜索;而通用算法find基于相等来搜索;可能导致结果不一样;
 
十、选择合适的排序算法
需要排序前思考我们的必要需求,可能我们只是需要前多少个元素,这时并不需要使用sort这种线性时间的工具,性能消耗更少的parttition可能是更好的选择;
以下算法的效率从左到右依次递减: 
partition > stable_partition / nth_element / patical_sort / sort / stable_sort
功能说明: 
partition         //将集合分隔为满足和不满足某个标准两个区间;
stable_partition  //partition的稳定版本;
nth_element       //获取任意顺序的前N个元素;
patical_sort      //获取前N个元素,这个N个元素已排序;
sort              //排序整个区间;
stable_sort       //sort的稳定版本;
 
 
posted @ 2017-09-29 11:26  心中的日月是你爸爸  阅读(101)  评论(0编辑  收藏  举报