高效使用STL
高效使用STL 参考:http://blog.jobbole.com/99115/
仅仅是个选择的问题,都是STL,可能写出来的效率相差几倍;
熟悉以下条款,高效的使用STL;
当对象很大时,建立指针的容器而不是对象的容器
1)STL基于拷贝的方式的来工作,任何需要放入STL中的元素,都会被复制;
这也好理解,STL工作的容器是在堆内开辟的一块新空间,而我们自己的变量一般存放在函数栈或另一块堆空间中;为了能够完全控制STL自己的元素,为了能在自己的地盘随心干活;这就涉及到复制;
而如果复制的对象很大,由复制带来的性能代价也不小 ;
对于大对象的操作,使用指针来代替对象能消除这方面的代价;
2)只涉及到指针拷贝操作, 没有额外类的构造函数和赋值构造函数的调用;
vecttor vt1; vt1.push_bach(myBigObj); vecttor vt2; vt2.push_bach(new BigObj());
注意事项:
1)容器销毁前需要自行销毁指针所指向的对象;否则就造成了内存泄漏;
2)使用排序等算法时,需要构造基于对象的比较函数,如果使用默认的比较函数,其结果是基于指针大小的比较,而不是对象的比较;
用empty() 代替size()来检查是否为空
因为对于list,size()会遍历每一个元素来确定大小,时间复杂度 o(n),线性时间;而empty总是保证常数时间;
尽量用区间成员函数代替单元素操作
使用区间成员函数有以下好处:
1)更少的函数调用
2)更少的元素移动
3)更少的内存分配
例:将v2后半部的元素赋值给v1:
单元式操作:
; ci != v2.end(); ++ci) v1.push_back(*ci)
使用区间成员函数assign():
v1.assign(v2.begin() + v2.size() / , v2.end());
使用reserver避免不必要的内存分配(for vector)
新增元素空间不够时,vector会进行如下操作:
1)分配当前空间的两倍空间;
2)将当前元素拷贝到新的空间中;
3)释放之前的空间;
4)将新值放入新空间指定位置;
如果预先知道空间的大小,预先分配了空间避免了重新分配空间和复制的代价;
注:reserve()只是修改了容量,并非大小,向vector中增加元素还是需要通过push_back加入;
使用有序的vector代替关联容器(阶段性的操作适用)
对阶段性操作的定义:
先做一系列插入、完成之后,后续操作都是查询;
在阶段性的操作下,使用vector有以下优势:
1)因为vector有序,关联容器带来的有序优势散失;
2)都是使用二分法查找的前提下,查询算法对连续的内存空间的访问要快于离散的空间;
在map的insert()和operator[]中仔细选择
插入时,insert效率高;因为operator会先探查是否存在这个元素,如果不存在就构造一个临时的,然后才涉及到赋值,多了一个临时对象的构造;
更新时,[]效率更高,insert会创造一个对象,然后覆盖一个原有对象;而[]是在原有的对象上直接赋值操作;
散列函数的默认比较函数是equal_to,因为不需要保持有序;
尽量用算法替代手写的循环
1)效率相比手写更高;
STL的代码都是C++专家写出来的,专家写出来的代码在效率上很难超越;
除非我们放弃了某些特性来满足特定的需求,可能能快过stl;比如,基于特定场合下的编程,放弃通用性,可移植性;
2)不容易出错;
3)使用高层次思维编程
相比汇编而言,C是高级语言;一条C语言语句,用汇编写需要好几条;
同样的,在STL的世界中,我们也有高层次的术语:
高层次的术语:insert/find/for_each(STL算法)
低层次的词汇:for /while(C++语法)
用高层次术语来思考编程,会更简单;
尽量用成员函数代替同名的算法
1)基于效率考虑,成员函数知道自己这个容器和其他容器有哪些特有属性,能够利用到这些特性;而通用算法不可以;
2)对于关联容器,成员函数find基于等价搜索;而通用算法find基于相等来搜索;可能导致结果不一样;
使用函数对象代替裸函数作为算法的输入参数
因为内联,在函数对象的方式中,内联有效,而作为函数指针时,一般编译器都不会内联函数指针指向的函数;即使指定了inline;
比如:
inline bool doubleGreater(double d1, double d2) { return dl > d2; } vector v; ... sort(v.begin(), v.end(), doubleGreater);
这个调用不是真的把doubleGreater传给sort,它传了一个doubleGreater的指针。
更好的方式是使用函数对象:
sort(v.begin(), v.end(), greater())
注:《effcient c++》中的实验结论,使用函数对象一般是裸函数的1.5倍,最多能快2倍多
选择合适的排序算法
需要排序前思考我们的必要需求,可能我们只是需要前多少个元素,这时并不需要使用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的稳定版本;
选择合适的容器
为什么vector不提供push_front()成员方法?因为效率太差,如果有太多从前面插入的需求,就不应该使用vector,而用list;
关心查找速度,首先应该考虑散列容器(非标准STL容器,如:unordered_map,unordered_set);其次是排序的vector,然后是标准的关联容器;
高效使用STL的更多相关文章
- STL --> 高效使用STL
高效使用STL 仅仅是个选择的问题,都是STL,可能写出来的效率相差几倍: 熟悉以下条款,高效的使用STL: 一.当对象很大时,建立指针的容器而不是对象的容器 1)STL基于拷贝的方式的来工作,任 ...
- C++ 之高效使用STL ( STL 算法分类)
http://blog.csdn.net/zhoukuo1981/article/details/3452118
- 鹅场offer已Get,下周签约,终于能静下心来总结总结
2015年9月20号下午,接到腾讯总部的电话,确定了offer相关信息,算是正式get了鹅场的offer,坐等下个周一周二的签约会. 心路篇 2015年2月:已经2月份了,自己在大学的时光已经来到了比 ...
- 高效的使用STL
高效的使用STL 仅仅是个选择的问题,都是STL,可能写出来的效率相差几倍: 熟悉以下条款,高效的使用STL: 当对象很大时,建立指针的容器而不是对象的容器 1)STL基于拷贝的方式的来工作,任何需要 ...
- stl map高效遍历删除的方法 [转]
for(:iter!=mapStudent.end():) { if((iter->second)>=aa) { //满足删除条件,删除当前结点,并指 ...
- stl map高效遍历删除的方法
for(:iter!=mapStudent.end():) { if((iter->second)>=aa) { //满足删除条件,删除当前结点,并指 ...
- 【腾讯Bugly干货分享】移动客户端中高效使用SQLite
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57b57f2a0703f7d31b9a3932 作者:赵丰 导语 iOS 程序能 ...
- 详细解说 STL 排序(Sort)
0 前言: STL,为什么你必须掌握 对于程序员来说,数据结构是必修的一门课.从查找到排序,从链表到二叉树,几乎所有的算法和原理都需要理解,理解不了也要死记硬背下来.幸运的是这些理论都已经比较成熟,算 ...
- STL标准模板库(简介)
标准模板库(STL,Standard Template Library)是C++标准库的重要组成部分,包含了诸多在计算机科学领域里所常见的基本数据结构和基本算法,为广大C++程序员提供了一个可扩展的应 ...
随机推荐
- [转载]破解TexturePacker加密资源
最近我们要开一个新项目,UI与交互打算借鉴当前正火的<圣火英雄传>,程序开发为了和美术制作并行,打算用圣火的资源暂代使用.我解压圣火apk,发现用TexturePacker命令行无法把它的 ...
- SPOJ 274 Johnny and the Watermelon Plantation(TLE)
O(n^3)的时间复杂度,改了半天交了二三十遍,TLE到死,实在没办法了…… 跪求指点!!! #include <cstdio> #include <cstdlib> #inc ...
- 《Linux内核设计与实现》读书笔记(十)- 内核同步方法【转】
转自:http://www.cnblogs.com/wang_yb/archive/2013/05/01/3052865.html 内核中提供了多种方法来防止竞争条件,理解了这些方法的使用场景有助于我 ...
- 《c程序设计语言》读书笔记--统计 行数、单词数、字符数
#include <stdio.h> int main() { int lin = 0,wor = 0,cha = 0; int flag = 0; int c; while((c = g ...
- samba linux windows 请联系管理员
在使用Samba进行建立Window与Linux共享时,要是不能访问,出现“您可能没有权限使用网络资源”, 那就是SELinux在作怪了 要是想让共享目录能访问,可以使用命令 #setenforce ...
- 自定义View(7)官方教程:自定义View(含onMeasure),自定义一个Layout(混合组件),重写一个现有组件
Custom Components In this document The Basic Approach Fully Customized Components Compound Controls ...
- android:descendantFocusability的作用:viewgroup与其上面view的焦点控制,如何让子view失去焦点等。
ViewGroup的下面这个属性可以控制. 原文: android:descendantFocusability Defines the relationship between the ViewGr ...
- 安全删除mysql binlog日志
命令行下执行 show binary logs; purge binary logs to 'mysql-bin.000070';
- UVa 548 (二叉树的递归遍历) Tree
题意: 给出一棵由中序遍历和后序遍历确定的点带权的二叉树.然后找出一个根节点到叶子节点权值之和最小(如果相等选叶子节点权值最小的),输出最佳方案的叶子节点的权值. 二叉树有三种递归的遍历方式: 先序遍 ...
- 51nod1394 差和问题
我只会用线段树写...不喜欢树状数组..其实跑的也不算慢?然后各种*的时候忘了longlong一直WA...药丸! 而且我不怎么会用map离散化...那么就sort+unique #include&l ...