CPP学习备忘[4] 性能

来源:互联网 发布:淘宝详情页的分辨率 编辑:程序博客网 时间:2024/06/05 01:05
 

【1】既要用函数调用来体现其结构化和可读性,又要使效率尽可能地高,解决办法就是将这种小函数声明为内联(inline);对函数的内联声明必须在调用之前,因为内联函数的代码在程序运行时是直接嵌在调用处执行的,它不影响链接,只在编译时确定运行代码,因此编译时ii,在调用之前看到内联声明就十分必要。

    内联函数使用的场合一般为:

1.     函数体适当小,这样就使嵌入工作容易进行,不会破坏原调用主体;

2.     程序中特别是在循环中反复执行该函数,这样就使嵌入的效率相对较高;

3.     程序并不多出出现该函数调用,这样就使嵌入工作量相对较少,代码量也不会剧增;

4.     内联函数中不能含有复杂的结构控制语句,如switch和while。如果内联函数有这些语句,则编译将无视内联声明,只是视同普通函数那样产生调用代码;

5.     递归函数也属于结构复杂的函数,也不能用来做内联函数;

6.     经验上,内联函数只适合于只有1~5行的小函数。对一个含有许多语句的大函数,函数调用的开销相对来说微不足道,所以也没有必要将函数内联;

7.     特别是在自定义数据类型的时候,会涉及大量的小函数定义,这些小函数会被频繁调用,所以,内联函数针对它们特别合适。

总之,内联函数是为了在不影响程序结构和可读性的前提下,提高程序性能。然而由于编译技术和机器指令结构的特点,内联函数必须具有小而简单的规模,并且处于经常被调用的环境中;

 

【2】STL中的容器,就是专家们长期实践中总结出来的最通用的几种数据结构,它们在C++中以模板类的形式出现,即可以容纳一切数据类型的数据集合,如向量(vector)、链表(list)、栈(stack)、队列(deque)等。程序员首选的方法是在STL中,选择容器来存储数据,只有在很特殊或很专业的情况下才自己定义或派生容器数据类型。

    事实上,90%以上的问题用向量来做就足够了,因为向量可以扩充,随机访问元素很方便。

 

【3】C++算法库是STL的一部分,算法实施的元素可以是具有自生自灭和多态的复杂对象。算法库总是对元素集合进行操作,标准算法调用中的参数需要指出元素集合的首尾位置,首位置的元素包含在算法处理中,尾位置是不包含在算法处理中的。指示元素位置并不是用下标,而是用迭代器对象,通俗地说就是指针,它的类型名称为“容器类型<元素类型>::iterator”,如整形向量的迭代器:vector<int>::iterator;

    多数情况下,要处理的数据为整个容器的的所有内容,这时候只要取容器的begin()与end()成员即可。end()即指向尾位置的元素(其实是不存在的那个元素)。

 

【4】C++提供了动态内存分配的new和delete操作。一般new和delete操作多用在内存需求捉摸不定的场合。当需要处理的数据变动范围很小时,可以用STL中通用型的容器来做,因为容器多能适应小量的变动需求。特别是,若大概知道元素的个数,就可以用reserve操作来预留若干空间,以免在频繁进行向量插入情形下,内存的频繁申请与释放内存操作了。

如vec.reserve(1100),它是为了应付向量不断插入所引起的频繁的内存申请释放操作。如果执行了该语句,vec向量一开始就会预留1100空间供反复插入之用。reserve不会改变向量中实际有的元素数,也就是说size的值不变。reserve可以控制向量既不浪费太多空间又使插入效率提高,还能应付元素个数不确切的复杂局面。在高级编程中,多数情况下容器的自动可扩性,可以代替动态内存分配的一般要求。

 

【5】低级编程是相对于面向对象或基于对象的抽象层次更高的高级编程而言,就是:

1.     不用C++STL的资源库,尽量减少内在的创建、调用、分配等的开销;

2.     对程序管辖的内存进行直接操作访问,无视数据类型的威力;

3.     尽量使用原始数据结构iu、数组和指针以及语言内部的运算符;

4.     能省则省,采用不利于模块化的编程方法,如溢用全局变量等;

5.     只能调用C函数库;

6.     在程序架构上多采用过程化程序设计方法;