高效使用STL
  仅仅是个选择的问题,都是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:
单元式操作:
for (vector::const_iterator ci = v2.begin() + v2.size() / ; 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,然后是标准的关联容器; 
 
 
ref:http://blog.jobbole.com/99115/
 

STL --> 高效使用STL的更多相关文章

  1. 高效使用STL

    高效使用STL  参考:http://blog.jobbole.com/99115/ 仅仅是个选择的问题,都是STL,可能写出来的效率相差几倍:熟悉以下条款,高效的使用STL: 当对象很大时,建立指针 ...

  2. STL笔记(2) STL之父访谈录

    年3月,dr.dobb's journal特约记者, 著名技术书籍作家al stevens采访了stl创始人alexander stepanov. 这份访谈纪录是迄今为止对于stl发展历史的最完备介绍 ...

  3. 跟我学STL系列(1)——STL入门介绍

    一.引言 最近这段时间一直都在自学C++,所以这里总结下自己这段时间的学习过程,通过这种方式来巩固自己学到的内容和以备后面复习所用,另外,希望这系列文章可以帮助到其他自学C++的朋友们. 由于本人之前 ...

  4. C++标准模板库Stand Template Library(STL)简介与STL string类

    参考<21天学通C++>第15和16章节,在对宏和模板学习之后,开启对C++实现的标准模板类STL进行简介,同时介绍简单的string类.虽然前面对于vector.deque.list等进 ...

  5. C++ 之高效使用STL ( STL 算法分类)

    http://blog.csdn.net/zhoukuo1981/article/details/3452118

  6. STL源代码分析——STL算法remove删除算法

    前言 因为在前文的<STL算法剖析>中,源代码剖析许多.不方便学习,也不方便以后复习,这里把这些算法进行归类.对他们单独的源代码剖析进行解说.本文介绍的STL算法中的remove删除算法. ...

  7. STL源代码分析——STL算法merge合并算法

    前言 因为在前文的<STL算法剖析>中.源代码剖析许多.不方便学习.也不方便以后复习,这里把这些算法进行归类.对他们单独的源代码剖析进行解说.本文介绍的STL算法中的merge合并算法. ...

  8. STL源代码分析——STL算法sort排序算法

    前言 因为在前文的<STL算法剖析>中,源代码剖析许多,不方便学习,也不方便以后复习.这里把这些算法进行归类,对他们单独的源代码剖析进行解说.本文介绍的STL算法中的sort排序算法,SG ...

  9. STL学习:STL库vector、string、set、map用法

    本文仅介绍了如何使用它们常用的方法. vector 1.可随机访问,可在尾部插入元素:2.内存自动管理:3.头文件#include <vector> 1.创建vector对象 一维: (1 ...

随机推荐

  1. 5.3 存储器、I/O和配置读写请求TLP

    本节讲述PCIe总线定义的各类TLP,并详细介绍这些TLP的格式.在这些TLP中,有些格式对于初学者来说较难理解.读者需要建立PCIe总线中与TLP相关的一些基本概念,特别是存储器读写相关的报文格式. ...

  2. 极限学习机︱R语言快速深度学习进行回归预测

    本文转载于张聪的博客,链接:https://ask.hellobi.com/blog/zason/4543. 深度学习在过去几年,由于卷积神经网络的特征提取能力让这个算法又火了一下,其实在很多年以前早 ...

  3. Microsoft+R:Microsoft R Open (MRO)安装和多核运作

    每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 本文转载于公众号大猫的R语言课堂,公众号作者使 ...

  4. vxWorks应用程序加载的另一种办法

    现在我们的工作中,应用程序一般都是和BSP联编,然后将vxworks_rom.bin烧到班子里.在BSP启动后,调用应用程序的函数的. 但是这样有个问题,就是应用程序和BSP结合的太紧密了.BSP开发 ...

  5. hibernate(二)主键生成策略

    hibernate主键生成策略主要指的是在实体类orm的配置 <id name=""> <generator class="native"&g ...

  6. java用Kruskal实现最小生成树

    今天更新这篇文章超级激动,因为我会最小生成树的算法了(其实昨天就开始研究了,只是昨天参加牛客网的算法比赛,结果又被虐了,好难过~) 最小生成树的算法,其实学了数据结构就会有一定的基础,Kruskal算 ...

  7. JavaScript设计模式(8)-装饰者模式

    装饰者模式 1. 作用: 可用来透明地把对象包装在具有同样接口的另一对象之中,这样可以给一个方法添加一些行为,然后将方法调用传递给原始对象. 可用于为对象增加功能,用来代替大量子类. 装饰者对其组件进 ...

  8. Python基础__字典、集合、运算符

    之前讨论的字符串.列表.元组都是有序对象,本节则重点讨论无序对象:字典与集合.一.字典 列表是Python中的有序集合,列表中的序指的是列表中的元素与自然数集形成了一个一一对应的关系.例如L=['I' ...

  9. HDU1166敌兵布阵(线段树,树状数组)

    题面 C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视这些工兵营地的活动情况 ...

  10. HDU 3416 Marriage Match IV(最短路,网络流)

    题面 Do not sincere non-interference. Like that show, now starvae also take part in a show, but it tak ...