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越大。性能区别越大。执行结构例如以下:
" 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++研究之在开发中你可能没有考虑到的两个性能优化的更多相关文章
- 在程序开发中怎样写SQL语句可以提高数据库的性能
以下内容是公司dba总结. 1. 首先要搞明白什么叫执行计划? 执行计划是数据库根据SQL语句和相关表的统计信息作出的一个查询方案,这个方案是由查询优化器自动分析产生的,比如一条SQL语句如果用来 ...
- 深入理解iOS开发中的BitCode功能
前言 做iOS开发的朋友们都知道,目前最新的Xcode7,新建项目默认就打开了bitcode设置.而且大部分开发者都被这个突如其来的bitcode功能给坑过导致项目编译失败,而这些因为bitcode而 ...
- Java 容器在实际项目开发中应用
前言:在java开发中我们离不开集合数组等,在java中有个专有名词:"容器" ,下面会结合Thinking in Java的知识和实际开发中业务场景讲述一下容器在Web项目中的用 ...
- 【初码干货】使用阿里云对Web开发中的资源文件进行CDN加速的深入研究和实践
提示:阅读本文需提前了解的相关知识 1.阿里云(https://www.aliyun.com) 2.阿里云CDN(https://www.aliyun.com/product/cdn) 3.阿里云OS ...
- Java开发中的23种设计模式详解
[放弃了原文访问者模式的Demo,自己写了一个新使用场景的Demo,加上了自己的理解] [源码地址:https://github.com/leon66666/DesignPattern] 一.设计模式 ...
- Unity游戏开发中的内存管理_资料
内存是手游的硬伤——Unity游戏Mono内存管理及泄漏http://wetest.qq.com/lab/view/135.html 深入浅出再谈Unity内存泄漏http://wetest.qq.c ...
- IOS 开发中要注意的事项
1.关于拍摄 TGCameraViewController – 基于 AVFoundation 的自定义相机.样式漂亮,轻量并且可以很容易地集成到 iOS 项目中.不会内存吃紧 2.block 中对控 ...
- fir.im Weekly - iOS开发中的Git流程
本期 fir.im Weekly 收集了微博上的热转资源,包含 Android.iOS 开发工具.源码等好用的轮子,还有一些 APP 设计的 Tips,希望对你有用. 精仿知乎日报 iOS 端 @我偏 ...
- iOS开发中 workspace 与 static lib 工程的联合使用
在iOS开发中,其实workspace的使用没有完全发挥出来,最近做了一些研究,也想把之前写过的代码整理下,因为iOS里面的布局方式,交互方式也就那么几种.所以,整理好了之后,更能快捷开发,而且能够形 ...
随机推荐
- PCB Genesis加邮票孔(线与弧)实现算法
一.Genesis加邮票孔(线与弧)实现算法 1.鼠标点击位置P点(可以确认搜索区域位置,确认点击位置周边元素分区,此所讲算法未应用到P点坐标) 2.求出:P1C与P2C (线与弧最近点距离的2个点) ...
- C - Stones on the Table
Problem description There are n stones on the table in a row, each of them can be red, green or blue ...
- JDK介绍
Java的版本最开始是1995年的JDK Alpha and Beta版本,第二年发布JDK1.0版本之后就是JDK1.1,JDK1.2.到1998年,不再叫JDK了,而是叫J2SE,但是版本号还是继 ...
- Spark Streaming概述
Spark Streaming是一种构建在Spark上的实时计算框架,它扩展了Spark处理大规模流式数据的能力. 其中包括:资源管理框架,Apache YARN.Apache Mesos:基于内存的 ...
- JavaScript 元素的插入顺序以及动态加载js
*****************记录下今天的心得***************** 1.元素的插入顺序 需求:异步从后台读取两个数据a和b,并动态加载到父容器x中,要求a必须在b的左边 实际情况:一 ...
- [hihocoder][Offer收割]编程练习赛59
替换函数 #pragma comment(linker, "/STACK:102400000,102400000") #include<stdio.h> #includ ...
- (转)用JS实现表格中隔行显示不同颜色
用JS实现表格中隔行显示不同颜色 第一种: <style> tr{bgColor:expression( this.bgColor=((this.rowIndex)%2==0 )? ...
- 【SQL】CONNECT BY 层次化查询
层次化查询,顾名思义就是把查询结果有层次的呈现出来.层次化查询结果类似于树状结构,最顶端的是“根节点”,下面是“父节点”,没有子节点的是“叶节点”. 为了让一个或多个表具有层次关系,必须使用相关的字段 ...
- IIS日志分析:SC-Status语义
在网站属性-网站-日志(属性) 中进行设定该站点IIS日志常规属性和扩展属性,扩展属性设置IIS日志包含字段显示. HTTP协议状态(sc-status)码的含义 IIS中 100 Continue ...
- (转)Arcgis for Js之GeometryService实现测量距离和面积
http://blog.csdn.net/gisshixisheng/article/details/40540601 距离和面积的测量时GIS常见的功能,在本节,讲述的是通过GeometryServ ...