内容简介:来源:公众号【编程珠玑】作者:守望先生ID:shouwangxiansheng
来源:公众号【编程珠玑】
作者:守望先生
ID:shouwangxiansheng
在分享这些性能优化技巧之前,需要说明以下几点
-
不要过早优化性能
-
现代编译器的优化能力很强大
-
80%的性能问题集中于20%的代码中
但是由于编译器的优化非常小心,它必须确保优化前后执行的效果是保持一致的,因此有些时候它会变得保守,并不能帮你优化太多。
本文所需要的是在平常不需要花费太多力气,养成习惯,并且对程序性能有好处的小技巧。
示例程序
为了说明本文所提到的技巧效果,先看一个示例程序,程序的目的非常简单,就是将字符串中的小写字母转换为大写),以下是完整可编译运行代码:
//来源:公众号【编程珠玑】
//作者:守望先生
//loop.c
#include<stdlib.h>
#include<stdio.h>
#include<time.h>
#include<ctype.h>
#include<string.h>
#include<sys/time.h>
#define MAX_LEN 1024*1024
void printCostTime(struct timeval *start,struct timeval *end)
{
if(NULL == start || NULL == end)
{
return;
}
long cost = (end->tv_sec - start->tv_sec) * 1000 + (end->tv_usec - start->tv_usec)/1000;
printf("cost time: %ld ms\n",cost);
}
int main(void)
{
srand(time(NULL));
int min = 'a';
int max = 'z';
char *str = malloc(MAX_LEN);
//申请失败则退出
if(NULL == str)
{
printf("failed\n");
return -1;
}
unsigned int i = 0;
while(i < MAX_LEN)//生成随机数
{
str[i] = ( rand() % ( max - min ) ) + min;
i++;
}
str[MAX_LEN - 1] = 0;
//统计时间
struct timeval start,end;
gettimeofday(&start,NULL);
for(i = 0;i < strlen(str) ;i++)
{
str[i] = toupper( str[i] );
}
gettimeofday(&end,NULL);
printCostTime(&start,&end);
free(str);
str = NULL;
return 0;
}
随机数的生成可参考《随机数生成的方法》。我们主要关注下面的部分:
for(i = 0;i < strlen(str) ;i++)
{
str[i] = toupper( str[i] );
}
很简单,对不对?
运行看看时间:
$ gcc - -o loop loop.c $ ./loop cost time: 42103 ms
总共花了42秒多!(机器处理能力不同运行结果将会有较大差异)
消除低效循环
终于来到了我们的优化环节,我们观察代码其实很容易发现,每次循环的时候都会执行一次strlen计算字符串的长度,而这个计算具有以下特点
-
每次结果一致,属于重复计算
-
strlen时间复杂度为O(N),也就是说,字符串越长,它需要的时间也就越多
一般情况下的使用是没有太大问题的,但是问题在于,如果是在一个多次循环中,它能极大的影响效率。
到这里,优化方法想必你也清楚了,那就是将计算结果不会改变的计算移到循环外。代码如下:
unsigned int len = strlen(str);
for(i = 0;i < len ;i++)
{
str[i] = toupper( str[i] );
}
那么再次运行的结果如何呢?
$ gcc -O0 -o loop loop.c $ ./loop cost time: 4 ms
看到没有,4ms,将近一万的性能提升!而这个数值将会随着字符串长度的增长进一步扩大。惊不惊喜,意不意外?
总结
实际上,本文的例子是比较极端的,然后实际中就可能隐藏着很多类似的代码:
-
在循环中计算,但是每次结果都一样
-
并且该计算的复杂度不是O(1)
对于这类代码,在不绝对影响可读性的情况下,完全可以将其移到循环外。
思考
如果是C++的string,循环时通过str.length()获取长度,会如此影响性能吗?为什么?
参考《深入理解计算机系统》
相关精彩推荐
讨论:科班和非科班出身的 程序员 有何差别?
关注公众号【编程珠玑】,获取更多Linux/C/C++/数据结构与算法/计算机基础/工具等原创技术文章。 后台免费获取经典电子书和视频资源
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- [译] 低效率开发人员的 4 种坏习惯
- 亚马逊启用AI人工智能监控系统 解雇900多名低效率员工
- 消除GitHub上的历史记录
- 消除单点,一篇搞定(架构设计篇)
- 网络协议传奇(五):大国阴影难消除
- NPM 采用 Rust 以消除性能瓶颈
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Design systems
Not all design systems are equally effective. Some can generate coherent user experiences, others produce confusing patchwork designs. Some inspire teams to contribute to them, others are neglected. S......一起来看看 《Design systems》 这本书的介绍吧!