代码优化

代码优化

并非所有的处理器级优化策略仅限于汇编。
即使C这样的高级语言中,也由不少适用的规则。

减少上下文依赖

看如下程序:

double list[100];
double sum = 0;
for (int i = 0; i < 100; i++) {sum += list[i];
}
上面这段代码还可以优化吗?站在C语言层面来说没有,但是站在处理器层面有: 
double list[100];
double sum1=0, sum2=0;
for (int i = 0; i < 100; i+=2) {sum1 += list[i];sum2 += list[i+1];
}
double sum = sum1+sum2;
循环展开

建议:不推荐
优点:减少循环次数(条件跳转次数)
缺点:增加了代码量,占用更多CPU内部一级代码高速缓冲区,可读性变差
描述:由于现代CPU具有分支预测技术,条件跳转已经很快,所以循环展开效果有限,而且这里累加每次都依赖于上一次的加法运算结果,这是一个线性的处理过程,而现代处理器在微操做级别,可以将临近多条指令同时处理,循环展开后就可以将一个线性处理链拆分为两个,那么处理器就可以同时处理两次加法运算

低效的静态变量

局部变量是在用到的时候才分配,而静态变量是一开始就分配好的,那么静态变量有更高的效率?
错误!局部变量存在于堆栈上,对其空间的分配,仅仅是在一个变量声明的语句块中,仅依靠单次修改esp寄存器就可以实现(一组局部变量的声明只需一次)
把变量放在堆栈上,带来的最大好处:函数能重复使用内存,这块内存被反复读写时,其数据就好存在于CPU内部一级缓存中,访问速度非常快。
绝大多数情况下,堆栈顶部的数据就符合这个条件,而静态变量则不同,内存和CPU内部缓存的数据交换,往往成为程序的速度瓶颈。

如果需要一个临时对象,使用new操作间接的调用malloc是十分低效的,高效做法应该是改用alloca在堆栈中分配内存。

注意绝大多数情况,有人喜欢局部声明巨大的数组,这很容器造成栈溢出,又会使得CPU内部缓存的映射不停的变动,破坏了CPU高度缓存带来的好处。所以要尽量避免。

若你需要一组全局变量,那么把它们放到一个类中,通过成员函数访问也可以提高效率(单例),通过唯一的this指针访问对CPU缓存很有利。

数据的组织

如果几个数据具有相关性,处理其中一个后很快就会处理接下来的另外几个,那么让这些数据物理上挨在一起效率更优。 

CPU处理数据时,最希望数据以对齐的方式存在于内存中,4字节和小于4字节的变量类型,希望以4字节方式对齐(即内存地址为4的位的地方) 而double是8字节,以8字节对齐最高效,还有比较大得结构,则希望以16字节对齐。

除法运算

整数运算和浮点运算中,除法都是很慢的指令,所以我们应该极力避免或者减少除法运算 注意:现代编译器会做很多优化工作,比如n/8优化为移位操作,a/3.14转化为乘法。
计算3次乘法也比计算一次除法速度快

避免过大的循环

比如:

// 方式1:
for (int i = 0; i < 100; i++) {todo_1();todo_2();
}
// 方式2:
for (int i = 0; i < 100; i++)todo_1();
for (int i = 0; i < 100; i++)todo_2();

上面程序哪个效率更好?
如果两个函数处理的逻辑都很简单,那么第一种方式更高效
如果两个函数处理的逻辑都很复杂,那么第二种方式更高效,原因在于CPU的代码缓存机制。
通常,程序代码第一次运行速度比较慢(如for循环第一次进入)。这存在一个代码从内存加载到CPU得时间,分支预测缓存的建立,甚至CPU对指令的解码。
如果循环体内涉及到的代码超过CPU的代码缓存容量,就会使得每次循环都会重新做一系列缓存工作,所以尽量维持循环中代码的尺寸。

参考:云风《游戏之旅-我的编程感悟》

转载于:https://www.cnblogs.com/luweimy/p/4180394.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/264008.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

3.3.10 动态SQL

十、动态SQL 根据条件的不同, SQL 语句也会随之动态的改变. MyBatis 中,提供了一组标签用于实现动态 SQL. 1. <if> 用于进行条件判断, test 属性用于指定判断条件. 为了拼接条件, 在 SQL 语句后强行添加 11 的恒成立条件. <select id"sel" resultType"…

无法载入 mysql 扩展

今天弄了一天&#xff0c;总算把win2003下的问题给解决了&#xff0c; LoadModule php5_module E:\server\php528\php5apache2_2.dll 可能有些朋友也知道&#xff0c;添加这句后&#xff0c;就不用把php.ini拷贝到系统目录&#xff1a; PHPIniDir E:\server\php528\php.ini 现在…

订阅mysql的二进制日志_MySQL二进制日志

一、二进制日志(The Binary Log)1、简介包含所有更新了的数据或者已经潜在更新了的数据(比如一条没有匹配任何行的delete语句)包含所有更新语句执行时间的信息不记录没有修改数据的语句例如select&#xff0c;show主要作用一&#xff1a;主从复制主要作用二&#xff1a;恢复数据…

AIX-vi操作-提示Unknown terminal type的问题解决方法

AIX-vi操作-提示Unknown terminal type的问题解决方法AIX Version 5.3$ vi /etc/profilelinux: Unknown terminal type[Hit return to continue] :q!I dont know what kind of terminal you are on - all I have is linux.[Using open mode]……临时办法&#xff0c;下次启动失…

javaEE jdbc编程步骤

版权声明&#xff1a;本文为博主原创文章。未经博主同意不得转载。 https://blog.csdn.net/qilixiang012/article/details/25925647 1.载入数据库驱动(jar文件) //须要下载一个数据库的jar包&#xff0c;并导入对应的JDBC项目中。创建路径&#xff01; Class.forName("co…

【备忘】XP欢迎页中隐藏用户名

HKEY_LOCAL_MACHINESoftware\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts\UserList 适用范围&#xff1a;Windows XP默认情况下&#xff0c;Windows XP会在登录界面中显示已经建立的用户账户名称。这样将方便恶意者猜测用户口令而进入系统&#xff0c;以下设…

centos镜像 from_【CentOS 7.1】使用163的镜像

CentOS 7.1.1503// backup[rootlocalhost yum.repos.d]# cd /etc/yum.repos.d/[rootlocalhost yum.repos.d]# mv CentOS-Base.repo CentOS-Base.repo.bakmv: overwrite ‘CentOS-Base.repo.bak‘? y[rootlocalhost yum.repos.d]#// wget[rootlocalhost yum.repos.d]# wget htt…

Java性能调优工具

2019独角兽企业重金招聘Python工程师标准>>> 1、JDK命令行工具 1.1、jps命令 jps用于列出Java的进程&#xff0c;jps可以增加参数&#xff0c;-m用于输出传递给Java进程的参数&#xff0c;…

转载:如何在 SQL Server 中使用配置选项调整内存使用量

查看( 4 ) / 评论( 0 ) / 评分( 0 / 0 ) 以前做过一个通过c#调用Excel组件生成Excel的小程序前几天PM打过电话来问, 说跑完以后为什么SQL Server内存占用这么大?服务器配置2G的内存, 程序正常执行完毕以后退出, SQL Server占用内存在1.7G, 而且没有被释放.因为怕可能会影响这个…

hive sql 报错后继续执行_Hive 执行sql命令报错

Failed with exception java.io.IOException:java.lang.IllegalArgumentException: java.net.URISyntaxException: Relative path in absolute URI: ${system:user.name%7D执行 show tables&#xff1b;出现上面的错误。错误原因修改 hive-site.xml 文件中的配置出现问题。# 编…

为什么要那么努力?

只是想着让我们前进的速度超过父母老去的速度。加油&#xff01;每个人的人生都不一样&#xff0c;做不一样的自己。元旦了&#xff0c;回家。转载于:https://www.cnblogs.com/kirinchang/p/4190103.html

python3将字符串unicode转换为中文

在我们的python使用过程中&#xff0c;可能会遇到这样的情况&#xff1a; 我们得到的中文数据是unicode编码类型的&#xff0c;这在python中是没有问题的&#xff0c;可以直接打印显示为中文。 但是&#xff0c;如果我们需要和其它语言或前端进行交互或需要存到数据库中的时候&…

连接SQL Server文件集锦

在新建SqlConnection对象&#xff0c;连接资料库时连接失败&#xff0c;出现“常规网络错误。请检查您的网络文档。” DataSource直接写IP的话&#xff0c;通信协议是按照TCP/IP协议连接的&#xff0c;如果服务器端TCP/IP服务没有开启&#xff0c;则会报错“不允许远程连接” A…

python 波形发生_事件与信号

事件 Event所有的GUI程序都是事件驱动的。事件主要由用户触发&#xff0c;但也可能有其他触发方式&#xff1a;例如网络连接、window manager或定时器。当我们调用QApplication的exec_()方法时会使程序进入主循环。主循环会获取并分发事件。在事件模型中&#xff0c;有三个参与…

Windows 注册和取消注册一个dll或者ocx

原文: Windows 注册和取消注册一个dll或者ocx 一、DLL是什么 DLL&#xff0c;是Dynamic Link Library 的缩写形式&#xff0c;中文名称为动态链接库。 DLL是一个包含可由多个程序同时使用的代码和数据的库&#xff0c;DLL不是可执行文件。动态链接提供了一种方法…

栈的相关操作

# include <stdio.h> # include <malloc.h> # include <stdlib.h>typedef struct Node {int data;struct Node * pNext; }NODE, * PNODE;typedef struct Stack {PNODE pTop;PNODE pBottom; }STACK, * PSTACK; //PSTACK 等价于 struct STACK *void init(PSTA…

HttpContext(三)-Request

ASP.NET RequestRequest封装了客户端请求信息&#xff0c;是从客户端得到数据&#xff0c;常用的三种取得数据的方法是&#xff1a;Request.Form、Request.QueryString&#xff0c;Request。其第三种是前两种的一个缩写&#xff0c;可以取代前两种情况。而前两种主要对应的Form…

jenkins学习笔记2-在centos中安装jenkins master测试环境

在centos中安装jenkins1&#xff09;安装目录pwd (/home/AAA)2&#xff09;检查java是否安装[AAACentos_AAA jenkins]$ java -version java version "1.6.0_22"OpenJDK Runtime Environment (IcedTea6 1.10.4) (rhel-1.41.1.10.4.el6-x86_64)OpenJDK 64-Bit Server V…

数据结构与算法6—树

树 树的表示方式有 树形图表示法:逻辑结构描述直观 嵌套集合表示法&#xff08;文氏图表示法&#xff09; 凹入表示法 广义表表示法 二叉树 二叉树是另一种重要的树形结构&#xff0c;是度为2的有序树&#xff0c;它的特点是每个结点至多有两棵子树。 二叉树的递归定义 二叉树…

动态改变stage桢数

动态改变stage桢数 stage.frameRate speed; 转载于:https://www.cnblogs.com/jiahuafu/archive/2010/03/29/1699434.html