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越大。性能区别越大。执行结构例如以下:

" src="http://www.cgzhw.com/wp-content/uploads/2014/08/13170935-21fcefcd83cf41f0b0fcca7b3def3719.png" style="">

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

" alt="C++研究之在开发中你可能没有考虑到的两个性能优化具体解释(二十五) - 第2张 | 成功智慧网-最好的游戏编程开发技术站点!" src="http://www.cgzhw.com/wp-content/uploads/2014/08/13171035-b5dc73ee74164eaaa964a8f54194267b.png" style="">

最基本的一句代码: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++研究之在开发中你可能没有考虑到的两个性能优化的更多相关文章

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

    以下内容是公司dba总结. 1. 首先要搞明白什么叫执行计划?   执行计划是数据库根据SQL语句和相关表的统计信息作出的一个查询方案,这个方案是由查询优化器自动分析产生的,比如一条SQL语句如果用来 ...

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

    前言 做iOS开发的朋友们都知道,目前最新的Xcode7,新建项目默认就打开了bitcode设置.而且大部分开发者都被这个突如其来的bitcode功能给坑过导致项目编译失败,而这些因为bitcode而 ...

  3. Java 容器在实际项目开发中应用

    前言:在java开发中我们离不开集合数组等,在java中有个专有名词:"容器" ,下面会结合Thinking in Java的知识和实际开发中业务场景讲述一下容器在Web项目中的用 ...

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

    提示:阅读本文需提前了解的相关知识 1.阿里云(https://www.aliyun.com) 2.阿里云CDN(https://www.aliyun.com/product/cdn) 3.阿里云OS ...

  5. Java开发中的23种设计模式详解

    [放弃了原文访问者模式的Demo,自己写了一个新使用场景的Demo,加上了自己的理解] [源码地址:https://github.com/leon66666/DesignPattern] 一.设计模式 ...

  6. Unity游戏开发中的内存管理_资料

    内存是手游的硬伤——Unity游戏Mono内存管理及泄漏http://wetest.qq.com/lab/view/135.html 深入浅出再谈Unity内存泄漏http://wetest.qq.c ...

  7. IOS 开发中要注意的事项

    1.关于拍摄 TGCameraViewController – 基于 AVFoundation 的自定义相机.样式漂亮,轻量并且可以很容易地集成到 iOS 项目中.不会内存吃紧 2.block 中对控 ...

  8. fir.im Weekly - iOS开发中的Git流程

    本期 fir.im Weekly 收集了微博上的热转资源,包含 Android.iOS 开发工具.源码等好用的轮子,还有一些 APP 设计的 Tips,希望对你有用. 精仿知乎日报 iOS 端 @我偏 ...

  9. iOS开发中 workspace 与 static lib 工程的联合使用

    在iOS开发中,其实workspace的使用没有完全发挥出来,最近做了一些研究,也想把之前写过的代码整理下,因为iOS里面的布局方式,交互方式也就那么几种.所以,整理好了之后,更能快捷开发,而且能够形 ...

随机推荐

  1. Python入门 六、像个 Pythonista

    pickle import pickle test_data = ['Save me!',123.456,True] f = file('test.data','w') pickle.dump(tes ...

  2. PCB WCF Web接口增减参数后,在客户端不更新的情况,是否影响客户端,评估测试

    1.目的:由于接口众多,服务端变更接口,会造成服务停用更新,造成客户端不能使用或报错, 在此评估[Web中心]此服务端,接口接口参数增加或减少,是否对客户端造成影响 2.评估内容:服务端增加单值参数, ...

  3. C Looooops(扩展欧几里得+模线性方程)

    http://poj.org/problem?id=2115 题意:给出A,B,C和k(k表示变量是在k位机下的无符号整数),判断循环次数,不能终止输出"FOREVER". 即转化 ...

  4. 洛谷P1402 酒店之王(二分图)

    P1402 酒店之王 题目描述 XX酒店的老板想成为酒店之王,本着这种希望,第一步要将酒店变得人性化.由于很多来住店的旅客有自己喜好的房间色调.阳光等,也有自己所爱的菜,但是该酒店只有p间房间,一天只 ...

  5. POJ 1659 Havel-Hakimi定理

    关于题意和Havel-Hakimi定理,可以看看http://blog.csdn.net/wangjian8006/article/details/7974845 讲得挺好的. 我就直接粘过来了 [ ...

  6. MVC微信浏览器图片上传(img转Base64)

    因公司业务需要,需要做一个微信公众号里的图片上传功能,主要用到的技术就是 img转base64 上到服务器 话不多说, 贴代码 先看前端显示出来的东西 OK 图片不重要,看代码 <!--微信图片 ...

  7. Struts2 在拦截器中向Action传参

    struts.xml配置文件: <package name="system-default" extends="struts-default" abstr ...

  8. 努比亚 Z17s (Nubia NX595J) 解锁BootLoader 并刷入recovery ROOT

    首先下载好工具链接:https://pan.baidu.com/s/1nw7BoZB 密码:zuun 备用下载链接:https://pan.baidu.com/s/1c3mUQGg 本篇教程教你如何傻 ...

  9. OpenCL C

    OpenCL C OpenCL  简介 opencl C是ISO C99的一个扩展,主要区别如下: 去除了C99的一些特性,如:标准C99头文件,函数指针,递归,变长数组,和位域 增加了一些特性用于并 ...

  10. Hive2.1.1集群搭建

    软件环境: linux系统: CentOS6.7 Hadoop版本: 2.6.5 zookeeper版本: 3.4.8 主机配置: 一共m1, m2, m3这五部机, 每部主机的用户名都为centos ...