网站首页 > 博客文章 正文
这篇文章代码执行效率的优化思路其实适用于任何编程语言的编程,也许仅仅方式不一样,底层逻辑是一样的,我们这里的讲解以C语言为例,希望大家一定耐心看完,对你优化代码效率一定有启发作用。
后续持续更新系列高质量文章,码字不易,欢迎关注、点赞、收藏。
原始代码
我们经常要做的一个事情就是要进行对矩阵进行操作运算,很多时候我们把矩阵数据存入一个数组里面,不管你要干什么,这里肯定涉及到对数组每一个元素的遍历。这里我们以二维数组为例,我们可以写出以下这样一段代码:
#include <stdio.h>
#include<stdlib.h>
#include<time.h>
int main()
{
int row,col;
time_t start, end;
time(&start);
for (row = 0; row <= 15000000; row++){
for (col = 0; col <= 200; col++){
}
}
time(&end);
printf("used time:%d s\n",(unsigned int)(end-start));
return 0;
}
代码非常简单,核心代码其实主要就是两个for循环,两层嵌套按照行与列与去遍历每一个成员,非常简单。
我们下面使用Ubuntu系统下GNU GCC编译器来编译一下生成可执行文件,同时使用time工具来看看这段代码执行耗时是多少(当然,我代码中也写了计算遍历耗时计算相关代码,并打印出来结果,效果都差不多,任意取之)。
可以看到耗时7.8秒,时间非常长,当然这里我模拟比较大的二维矩阵,行数为15000000,列为200,所以矩阵很大,耗时比较长。
优化代码
下面我们对上述简单代码只做一个简单修改,就是在对行列两个循环变量int row,col前面加一个register关键字,变成register int row,col。新代码如下:
#include <stdio.h>
#include<stdlib.h>
#include<time.h>
int main()
{
register int row,col;
time_t start, end;
time(&start);
for (row = 0; row <= 15000000; row++){
for (col = 0; col <= 200; col++){
}
}
time(&end);
printf("used time:%d s\n",(unsigned int)(end-start));
return 0;
}
下面如上的方式,我们来看看这个新程序的数组遍历耗时结果。
我们可以看到这个程序耗时仅仅为1.4秒,是原始代码的大约1/6,效率提高6倍,好神奇啊!加了一个关键字register,就效率提升这么多,这是为什么呢?
register关键字是什么?
register是寄存器的意思,C语言变量前面加register,表示是寄存器变量。
这关键字的作用是让编译器将这个变量存储在CPU的寄存器中,而不是放在内存中。如果不加register关键字,那变量就是普通变量,存储于内存RAM中。
优化效果解析
寄存器变量的引入使得计数器 row和col被存储在寄存器中,而不是在内存中。这样做的优势在于,寄存器的访问速度远远快于内存,因此可以显著提高循环的执行效率。
为了更好地理解这一点,让我们来看一下计算机的内存结构层次图:
在这个层次结构中,寄存器位于顶部,是最快速的存储器,但容量最小。高速缓存相对较快,但容量更大。主存(RAM)速度较慢,但容量更大,而辅助存储设备(硬盘等)则是最慢但最大容量的存储器。
通过将变量存储在寄存器中,我们可以减少对相对较慢的主存的访问,从而提高程序的整体性能。在上面的数组的遍历循环中,这种优化特别重要,尤其是较多次循环,因为它涉及对变量row和col的频繁访问,而这些变量如果能够存储在寄存器中,就能够更快速地被访问和处理。
循环中的每次迭代都需要对i进行递增和求和操作,而这些操作现在都可以在寄存器中进行,而无需频繁地与内存交互。这减少了内存总线的压力,减小了访问延迟,从而加速了代码的执行。
这也说明了寄存器变量并不仅仅是一种语法上的优化,而是直接与计算机体系结构的层次有关,通过合理利用寄存器,我们可以充分发挥硬件的性能潜力。
需要注意的是,寄存器变量并不总是带来性能提升,因为寄存器的数量是有限的,而编译器也会根据上下文进行变量的寄存器分配。因此,程序员在使用寄存器变量时应该谨慎,根据具体情况权衡性能提升和编程规范。
在实际项目中,可以通过编译器提供的性能分析工具,如GCC的 -O2 或 -O3 选项,来进一步优化代码并评估性能提升效果。
优化通用思路总结
我们这里不是为了讲寄存器变量,重点是让大家理解一个优化代码效率的通用思路:
对于访问次数非常频繁的数据,在条件允许的前提下,建议将该数据尽量放到访问速度最快的硬件存储介质存储,从而从底层硬件读写上提高效率,最终提高代码执行效率。
猜你喜欢
- 2024-09-12 亚马逊自研Graviton4芯片实测,比英特尔至强8488C快5%
- 2024-09-12 Linux Ubuntu系统部署C++环境的方法
- 2024-09-12 ubuntu下安装CUDA,cuDNN及pytorch-gpu版本的步骤教程
- 2024-09-12 Ubuntu 20.04 CUDA&cuDNN安装方法
- 2024-09-12 手把手教你在 Ubuntu16.04 安装 GPU 驱动 + CUDA9.0 + cuDNN7
- 2024-09-12 ubuntu 19.10有什么新特性?(ubuntu 20.10 新特性)
- 2024-09-12 Ubuntu 24.10 开发代号确定为 "Oracular Oriole"
- 2024-09-12 Ubuntu 20.10迎来最后一个Beta测试版本
- 2024-09-12 如何在Linux系统上安装最新版本的VMware
- 2024-09-12 Ubuntu 24.04 LTS 默认内核将采用 Linux 6.8
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- powershellfor (55)
- messagesource (56)
- aspose.pdf破解版 (56)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- jwt漏洞 (58)
- macos14下载 (58)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- vue回到顶部 (57)
- qcombobox样式表 (68)
- vue数组concat (56)
- tomcatundertow (58)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)