5章 优化程序性能
来源:互联网 发布:淘宝的收入来源 编辑:程序博客网 时间:2024/06/10 19:18
主要探讨如何使用几种不同类型的程序优化技术,使程序运行更加快。
主要结合硬件解释了如何优化,这章不必深入追究,追究也不会明白。
必须写出清晰简洁的代码,这样左不仅为了程序员能够看懂代码,也是为了在检查代码时,别人能够读懂和理解代码。
不依赖于目标机器特性的优化
选择合适的算法和数据结构是前提,然后再进行1、2、3的基本优化。
1、消除循环的低效率
消除循环的条件测试中一些计算结果不会改变的计算。这种很简单的方法称为代码移动。编译器自己也会尽可能代码移动,但是可能调用函数具有副作用那么优化移动失败,这种情况下必须显示地帮助编译器完成代码移动,增加程序性能
2、消除不必要的过程调用
过程调用,创建栈帧会造成不小的开销,所以可以不用过程调用的地方尽量不用过程调用,直接内联即可。
3、消除不必要的存储器引用
引入临时变量(编译器会分配寄存器存储,寄存器访问快速)来存储结果,最后计算结果放回数组或全全局变量或传入地址操作,可以加速程序性能。
int strlen(const char *s)//只需要一个const,表示s不能改变s指向的数值,后面一个const不需要,因为s是形参,是实参的压栈,在这里没必要保护形参{ int len; while(*s++ != '\0') len++; return len;}//大写字母比小写字母数字小32void lower(char *s){ int i; for(i = 0 ; i < strlen(s) ; i++ ){ if(s[i] >= 'A' && s[i] <= 'Z') s[i] += ('a' - 'A'); }}void lower1(char *s){ int i; int len = strlen(s);//这句话就是简单的代码移动,对于大字符串,这相当有用, //写代码就应该时刻记住这种代码移动,增加性能。时刻记住大数据。 for(i = 0 ; i < len ; i++ ){ if(s[i] >= 'A' && s[i] <= 'Z') s[i] += ('a' - 'A'); }}
#define IDENT 1//向量操作初始值#define OP *//乘typedef struct { long int len; data_t *data;}vec_rec, *vec_ptr;vec_ptr new_vec(long int len)//返回长度为len的向量{ vec_ptr result = (vec_ptr) malloc(sizeof(vec_rec));//分配一个结构体头,指向存储向量的一维数组 if (!result) return NULL; /* */ result->len = len; result->allocated_len = len; if (len > 0) { data_t *data = (data_t *)calloc(len, sizeof(data_t));//分配一维数组 if (!data) { free((void *) result); return NULL; /* */ } result->data = data; } else result->data = NULL; return result;//返回头指针,头指针和存储向量的地方,全部动态分配.}int get_vec_element(vec_ptr v, long int index, data_t *dest)//通过索引获取向量元素{ if (index < 0 || index >= v->len)//防止越界 return 0; *dest = v->data[index]; return 1;}long int vec_length(vec_ptr v){ return v->len;}data_t *get_vec_start(vec_ptr v)//返回向量首地址{ return v->data;}void combine1(vec_ptr v, data_t *dest)//最原始操作,没有经过任何软件优化{ long int i; *dest = IDENT; for (i = 0; i < vec_length(v); i++) { data_t val; get_vec_element(v, i, &val); *dest = *dest OP val; }}void combine2(vec_ptr v, data_t *dest)//消除了循环中的低效率部分,减少了条件判断中函数的调用{ long int i; long int length = vec_length(v); *dest = IDENT; for (i = 0; i < length; i++) { data_t val; get_vec_element(v, i, &val); *dest = *dest OP val; }}void combine3(vec_ptr v, data_t *dest)//消除了循环中的低效率部分,较少了循环内部的过程调用,直接通过数组索引数值{ long int i; long int length = vec_length(v); data_t *data = get_vec_start(v); *dest = IDENT; for (i = 0; i < length; i++) { *dest = *dest OP data[i]; }}void combine4(vec_ptr v, data_t *dest)//消除了循环中不必要的内器读写(dest)。通过分配局部变量acc(此时必定分配在寄存器)。最后仅仅一次写搞定{ long int i; long int length = vec_length(v); data_t *data = get_vec_start(v); data_t acc = IDENT; for (i = 0; i < length; i++) { acc = acc OP data[i]; } *dest = acc;}
对于上述combine3和combine4,编译器不会自动将combine3优化为combine4,因为由于存储器的别名,将导致二者函数调用计算的结果不一样。
combine3(v , get_vec_start(v));//目的地址是第一个元素combine4(v , get_vec_start(v));//目的地址是第一个元素//二者产生结果明显不一样
依赖于目标机器特性的优化
这里主要涉及循环展开(减少循环迭代次数)等,一些操作依赖于处理器体系结构,相对比较复杂,暂时不用考虑。
小结
明白一些程序的优化,更复杂和体系结构有关的暂时先不用考虑。优化的优先原则就是选择好的数据结构和算法。
阅读全文
1 0
- 5章 优化程序性能
- 第5章 优化程序性能
- 第五章 优化程序性能
- 第五章 优化程序性能
- java程序性能优化第三章
- Java性能优化:程序优化
- Java程序性能优化 !
- Java程序性能优化
- Java程序性能优化 !
- Java程序性能优化
- Java程序性能优化
- java程序性能优化
- Java程序性能优化
- Java程序性能优化
- Java程序性能优化
- Hibernate程序性能优化
- Java程序性能优化
- Java程序性能优化
- Postman讲解
- log4j日志简单配置及使用
- Java数据基本类型
- selenium在win7 64上的安装和配置
- 如何防止别人恶意调用API接口?
- 5章 优化程序性能
- 解决js函数replace禁止输入框输入非法字符,光标回到文字最后问题
- Scratch编程教程
- 记录用到的地址
- RIP协议-解析
- Error:This Gradle plugin requires Studio 3.0 minimum
- Oracle数据库查看编码和修改编码
- linux rzsz(lrzsz)安装
- leetcode解题方案--054--spiral maxtrix