C++研究之在开发中你可能没有考虑到的两个性能优化



1:多余的存储引用导致性能降低;

2:利用局部性提高程序性能;

先来说说引用是怎么降低程序性能,个人认为降低程序性能主要有两个原因,一是数据结构选择不合理,二是多层嵌套循环导致部分代码被多余重复执行。在第二种情况下我们一般都是优化循环最里层的代码,能提出来的尽量往外层提,实在不行的就优化它的运行速度。

1:多余的存储引用导致性能降低。先来看一个关于引用导致性能降低的问题。下面两个方法哪个更快。

static void Test2(ref int sum)
        {
            for (int i = 1; i <= timer; i++)
            {
                sum += i;
            }
        }

        static void Test3(ref int sum)
        {
            int tmpSum = sum;
            for (int i = 1; i <= timer; i++)
            {
                tmpSum += i;
            }
            sum = tmpSum;
        }

大致一看他们的性能应该没有差别,因为这两个方法其实就是利用一个循环求和,而真正能影响方法的性能就是这个循环,且两个方法的循环表面上看可以说是一样的,当,我令timer=10000000时,即求1+2+…+10000000的和,方法Test3的速度比Test2快。是的,Test3比Test2快,在某个区间内timer越大,性能差别越大。运行结构如下:

咱们直接来看反汇编代码,部分反汇编代码如下,我们只用看红线框着的部分。

最主要的一句代码:sum+=i;方法Test2比方法Test3多了最后面一行,即将每次循环后求得的和回写到内存中,方法Test3却不用这么麻烦,只用一个寄存器,每次求得的和写到寄存器中,求完和后一次将和写到内存中。在每次循环中,Test2要读两次内存(sum和i都从内存中读),写一次内存(将求得的和写到内存中),而方法Test3只需要读一次内存,即从内存中读i的值,方法Test3的性能比Test2高就不言而喻了。就因为Test2每次都是以引用的方式读sum的值,CPU要得到sum的值,就得通过sum在内存中的地址,所以必读内存,,而Test3不必读内存,用一个寄存器即可。

技术提高的访问www.cgzhw.com 游戏编程网很不错的技术网站。

2:利用局部性提高程序性能。还是直接看一个简单的例子

static int Test4(int[,] arr, int row, int column)
        {
            int sum = 0;
            for (int i = 0; i < row; i++)
            {
                for (int j = 0; j < column; j++)
                {
                    sum += arr[i, j];
                }
            }
            return sum;
        }

        static int Test5(int[,] arr, int row, int column)
        {
            int sum = 0;
            for (int j = 0; j < column; j++)
            {
                for (int i = 0; i < row; i++)
                {
                    sum += arr[i, j];
                }
            }
            return sum;
        }

简单一个看,两个方法几乎是完全一样,不同的是Test4是按行求和,而Test5是按列求和。如果多次执行这两个方法进行,对比就会方法Test4的性能高于Test5。运行两个方法100000次,结果如下:

为什么按行求和比按列求和快呢?简单一句话:数组是按行存的。CPU每次从内存读数据,不是要哪个就读哪个就直接读哪个,而是每次读一个高速缓存行,就是每次要多读一些,如,果需要的数据在高速缓存行中,就不用到内存中去读了,而是直接从高速缓存行中取,当然就比再从内存中读取要快一些。而在这里,数组按行存储,也就是说,CPU每次会读多个数组元素导高速缓存行,如果需要的元素在高速缓存行中就不用到内存中去取了,这就是传说中的命中率,按行求和命中率当然就高了。而按列求和,命中率自然低,CPU每次将一行中的多个元素读到高速缓存行中,按列求和每次只需要一个元素,也就是每次只需要一个元素而CPU却读了多个元素,命中率当然低,低到可能出现命中率为0。

程序的局部性包括:空间局部性和时间局部性,这里说的就是空间局部性。

空间局部性就是说一个被使用的到数据其周围的数据很可能会被马上使用。

时间局部性就是说一个被使用的到数据很可能会被再次使用。

C++研究之在开发中你可能没有考虑到的两个性能优化

时间: 2024-10-09 23:33:53

C++研究之在开发中你可能没有考虑到的两个性能优化的相关文章

JAVA开发之大型互联网企业高并发架构Tomcat服务器性能优化视频教程

课程目标熟练掌握高并发架构Tomcat服务器性能优化. 适用人群对计算机,java开发人员,Java架构师,运维感兴趣的朋友! 课程简介Tomcat是Apache软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache.Sun和其他一些公司及个人共同开发而成.Tomcat服务器是一个免费的开放源代码的Web应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP程序的首选. Tomc

在程序开发中怎样写SQL语句可以提高数据库的性能

以下内容是公司dba总结. 1. 首先要搞明白什么叫执行计划?   执行计划是数据库根据SQL语句和相关表的统计信息作出的一个查询方案,这个方案是由查询优化器自动分析产生的,比如一条SQL语句如果用来从一个10万条记录的表中查1条记录,那查询优化器会选择"索引查找"方式,如果该表进行了归档,当前只剩下5000条记录了,那查询优化器就会改变方案,采用"全表扫描"方式. 可见,执行计划并不是固定的,它是"个性化的".产生一个正确的"执行计划

Python成为编程语言中的第一!送你20条Python性能优化的建议!

1.优化算法时间复杂度 算法的时间复杂度对程序的执行效率影响最大,在Python中可以通过选择合适的数据结构来优化时间复杂度,如list和set查找某一个元素的时间复杂度分别是O(n)和O(1).不同的场景有不同的优化方式,总得来说,一般有分治,分支界限,贪心,动态规划等思想. timeit后面的-n表示运行的次数,后两行对应的是两个timeit的输出,下同.由此可见后者慢一个数量级. 进群:548377875  即可获取数十套PDF哦! 但是对于需要循环遍历的情况: 对于内存不是非常大的lis

Android实际开发中的首页框架搭建(二、首页框架实现)

本来这一篇是前两天就要写的,奈何事多缠身,推到今日,为自己的拖延感到愧疚... 上一篇大概把项目的结构完成了,下一步就是实现首页切换功能了 首先在activity目录下新建一个HomeActivity,作为承载多个fragment的容器 代码如下 1 /* 2 * * 3 * * ******************************************************* 4 * * 5 * * @文件名称:HomeActivity.java 6 * * @文件作者:ouyan

深入理解iOS开发中的BitCode功能

前言 做iOS开发的朋友们都知道,目前最新的Xcode7,新建项目默认就打开了bitcode设置.而且大部分开发者都被这个突如其来的bitcode功能给坑过导致项目编译失败,而这些因为bitcode而编译失败的的项目都有一个共同点,就是链接了第三方二进制的库或者框架,而这些框架或者库恰好没有包含bitcode的东西(暂且称为东西),从而导致项目编译不成功.所以每当遇到这个情况时候大部分人都是直接设置Xcode关闭bitcode功能,全部不生成bitcode.也不去深究这一开关背后隐藏的原理.中枪

【初码干货】使用阿里云对Web开发中的资源文件进行CDN加速的深入研究和实践

提示:阅读本文需提前了解的相关知识 1.阿里云(https://www.aliyun.com) 2.阿里云CDN(https://www.aliyun.com/product/cdn) 3.阿里云OSS(https://www.aliyun.com/product/oss) 4.HTTPS(http://baike.baidu.com/view/14121.htm) 阅读目录结构 引: 一.准备工作 二.整体功能结构 三.具体实现步骤 四.关键点和问题处理 五.延伸与扩展 六.总结与思考 引:

对于软件开发中开发人员与测试人员关系的理解

在软件开发中都会有开发人员(以下简称开发)和测试人员(以下简称测试),在一些小型公司可能并没有测试,仅仅是开发兼任测试.在这里我仅针对于有专业的测试和专业的开发的项目. 每个公司应该都有考核机制,对于开发和测试的考核实际上很难量化,通常来讲大的方向就是开发所负责模块的bug数,对于测试来讲就是测出来的bug数,但这真的有效吗?这也许对开发有约束力,理论上开发是能够自己控制bug数的,如果从产生的bug数来评判开发的绩效还算有效,这样开发自然就会把代码写得更加认真.但如果根据测试测出来的bug数来

ios开发中-AFNetworking 的简单介绍

Blog: Draveness 关注仓库,及时获得更新: iOS-Source-Code-Analyze 在这一系列的文章中,我会对 AFNetworking 的源代码进行分析,深入了解一下它是如何构建的,如何在日常中完成发送 HTTP 请求.构建网络层这一任务. AFNetworking 是如今 iOS 开发中不可缺少的组件之一.它的 github 配置上是如下介绍的: Perhaps the most important feature of all, however, is the ama

在Winform开发中使用日程控件XtraScheduler(2)--深入理解数据的存储

在上篇随笔<在Winform开发中使用日程控件XtraScheduler>中介绍了DevExpress的XtraScheduler日程控件的各种使用知识点,对于我们来说,日程控件不陌生,如OutLook里面就有日历的模块,但是这个日程控件真的是很复杂的一个控件,需要全面掌握可能需要花费很多的时间去了解,由于是技术研究,我总是希望把它常用的功能剖析的更加彻底一些,前面随笔也介绍了它的存储功能,把它基于实体类的方式存储在数据库里面,不过介绍的还不够,本文继续上面的内容,进行数据存储方面的介绍. 在