当前位置: 首页 > 编程日记 > 正文

[摘录]代码优化规则

<<代码优化:有效使用内存>>代码优化建议:
    1. 展开读取内存的循环
    2. 消除数据相关性

        如果请求的RAM单元存在地址数据相关性(也就是说,一个单元含有另一个单元的地址),那么CPU不能并行地处理它们,而在得到地址之前必须等待。消除数据相关性可以提高指令并发度。
    3. 同时向存储控制器发送多个查询
    4. 请求按不少于32个字节的增量方式读取数据
   
在 于内存进行数据交换的过程中所用的最小数据单位至少是32byte,所以处理速度与处理增量成反比。当增量以1(字节、字或双字)读取内存时,由一半的加 载单元永远不会访问。当以增量4(字节、字或双字)读取内存时,仅仅有25%的加载单元会用到,其它的加载单元不会起任何作用。可见,内存中的数据必须尽 可能紧密地存放在一起。
    5. 使用所有经历请求的页面
    6. 以一种排除了对相同DRAM页面进行选取的增量方式来处理数据
    7. 对齐数据源地址
    8. 组合执行存取内存的代码
    9. 成组进行读写操作
    10. 仅仅在必要时才放问内存
    11. 从不针对特定平台优化程序。

<<Programming Pearls(Second Edition)>>代码优化规则:


1. 用空间换取时间规则
    1.1 扩展数据结构:通常,通过给结构增加其他信息或改变结构内部的信息让它访问的更快能够减少对数据的常用操作所需的时间。
    1.2 存储预先计算好的结果:
计算函数一次,然后存储计算结果能够减少昂贵函数的重新计算所需要的成本。以后对该函数的请求就只需要通过查表来完成,而不需要重新计算该函数。
    1.3 高速缓存:必须降低经常访问的数据的访问成本。
    1.4 延迟计算法:
除非需要,否则该策略永远不会计算某个元素,这样可以避免计算不必要的元素。


2. 用时间换取空间规则
    2.1 压缩:
密集存储表示能够通过增加存储和检索所需的时间来降低存储成本。
    2.2 解释程序:通常,使用解释程序能够减少表示程序所需的空间,解释程序压缩表示相同的操作序列。


3. 循环规则
    3.1 将代码移出循环:
最好不要在循环的每次迭代中都执行相同的操作,而是将它放在循环外部,仅仅执行一次。
    3.2 合并测试条件:高效的内部循环一个尽量少包含测试条件,最好只有一个。因此,程序员应该尽量使用其他退出条件模拟循环的一些推出条件。哨兵是该规则最常见的应用:在数据结构的边界上放一个哨兵来测试是否已经遍历完整个结构。
    3.3 循环展开:展开循环能够消除循环中修改循环下标的成本,同时一能避免管道时延、减少分支,并增加指令级并发。
    3.4 传输驱动的循环展开:如果在普通的赋值中,使用了一个成本很高的内部循环,那么通常通过改变所使用的变量能够消除这些赋值。例如:删除赋值i=就,后面的代码必须将j视为i。
    3.5 消除无条件分支:在快速的循环中不应该包含无条件分支。通过“旋转”循环,在底部加上一个条件分支,能够消除循环结束处的无条件分支。
    3.6 循环合并:如果两个邻近的循环操作作用在同一个元素集上,那么最好合并这两个操作部分,仅仅使用一个循环控制操作


4. 逻辑规则
    4.1 利用袋鼠恒等式:
如果逻辑表达式的计算非常昂贵,就使用比较廉价的代数等式表达式来替换。
    4.2 简化的单调函数:
测试几个部落的单调非递减函数是不是超过了特定的阀值,一旦达到了这个阀值就不需要计算任何变量。该规则的一个更加复杂的应用就是一旦达到了循环的目的就退出循环。
    4.3 重新排序测试:在组织逻辑测试的时候,应该将廉价的经常成功的测试放在昂贵的很少成功的测试前面。
    4.4 预计算逻辑函数:可以使用表示域的表的查找替代一个小的有限域中的逻辑函数。
    4.5 消除布尔变量:我们可以通过用if-else语句替代对布尔变量的v赋值来消除布尔变量,在if-else语句中的一个分支表示v为真的情况,其它的表示v为假的情况。


5. 过程规则
    5.1 压缩函数层次:
通常,重写函数并绑定过去的变量能够减少调用本身(非递归)函数集合元素的运行时间。
    5.2 利用常用情况:
一个组织函数正确处理所以情况并高效处理普通情况。
    5.3 协同程序:通常,使用协同程序能够将multiple-pass算法转换为single-pass算法。
    5.4 递归函数变化:
通过下面的转换能够减少递归函数的运行时间:将递归重写为迭代,通过使用栈来将递归转换为迭代。如果函数的最后一步是递归调用自身,那么使用一个到其第一条语句的分支来替换该调用,这通常叫做尾递归。
    5.5 并发:在基本的硬件条件下,构建的程序应该能够尽可能地利用并发。


6. 表示规则
    6.1 初始化编译时间:
在程序执行之前,尽可能初始化变量。
    6.2 利用代数恒等式:如果表达式的计算非常昂贵,就应使用开销较小的代数恒等表达式替换它。通常我们可以是向左或向右移位来实现幂的乘或除;尽量减少数组元素上的迭代循环,使用加法替代乘法。
    6.3 消除通用子表达式:如果连续两次计算了同一个表达式,并且它的所有变量都没有任何改动,那么就应该避免第二次计算,只需要排序第一次计算结果并将它用于第二次计算中。现在的编译器一般都能消除不包含函数调用的常用子表达式。
    6.4 配对计算:如果总是同时计算两个类似的表达式,那么就应该建立一个新的过程并将它们成对计算。
    6.5 利用单词并发:充分使用基本计算机体系结构的数据总线宽度来计算昂贵的表达式。

转载于:https://www.cnblogs.com/jimcsharp/p/5577261.html

相关文章:

伍六七带你学算法 入门篇-拼写单词

力扣解题&#xff0c;每日一题 1160. 拼写单词 难度- 简单 给你一份『词汇表』&#xff08;字符串数组&#xff09; words 和一张『字母表』&#xff08;字符串&#xff09; chars。 假如你可以用 chars 中的『字母』&#xff08;字符&#xff09;拼写出 words 中的某个『单…

linux内核调优参考

对于新部署的机器&#xff0c;需要做一些基本的调优操作&#xff0c;以更改一些默认配置带来的性能问题 1 修改打开文件数 rootmysql:/data/tools/db# vim /etc/security/limits.conf * soft nofile 65535 * soft nproc 65535…

伍六七带你学算法 入门篇-最长回文串

力扣解题&#xff0c;每日一题&#xff1a;409. 最长回文串 难度- 简单 给定一个包含大写字母和小写字母的字符串&#xff0c;找到通过这些字母构造成的最长的回文串。 在构造过程中&#xff0c;请注意区分大小写。比如 “Aa” 不能当做一个回文字符串。 注意: 假设字符串…

bzoj1095: [ZJOI2007]Hide 捉迷藏 线段树维护括号序列 点分治 链分治

这题真是十分难写啊 不管是点分治还是括号序列都有一堆细节。。 点分治&#xff1a;时空复杂度$O(n\log^2n)$&#xff0c;常数巨大 主要就是3个堆的初始状态 C堆&#xff1a;每个节点一个&#xff0c;为子树中的点到它父亲的距离的堆。 B堆&#xff1a;每个节点一个&#xff0c…

伍六七带你学算法 入门篇-最小的k个数

java面试题-最小的k个数 难度-简单 输入整数数组 arr &#xff0c;找出其中最小的 k 个数。例如&#xff0c;输入4、5、1、6、2、7、3、8这8个数字&#xff0c;则最小的4个数字是1、2、3、4。 示例 1&#xff1a; 输入&#xff1a;arr [3,2,1], k 2 输出&#xff1a;[1,2] …

伍六七带你学算法 进阶篇-三数之和

三数之和 难度-中等 题目&#xff1a;给你一个包含 n 个整数的数组 nums&#xff0c;判断 nums 中是否存在三个元素 a&#xff0c;b&#xff0c;c &#xff0c;使得 a b c 0 &#xff1f;请你找出所有满足条件且不重复的三元组。 注意&#xff1a;答案中不可以包含重复的三…

伍六七带你学算法 入门篇-链表的中间节点

力扣-876链表的中间节点 难度-简单 给定一个带有头结点 head 的非空单链表&#xff0c;返回链表的中间结点。 如果有两个中间结点&#xff0c;则返回第二个中间结点。 示例 1&#xff1a; 输入&#xff1a;[1,2,3,4,5] 输出&#xff1a;此列表中的结点 3 (序列化形式&#xf…

伍六七带你学算法 入门篇-卡牌分组

力扣-914. 卡牌分组 难度-简单 这是一道非常有趣的题&#xff0c;提交通过率令人深思 &#xff0c;思考它是不是一道简单的题… 开始正题&#xff1a; 给定一副牌&#xff0c;每张牌上都写着一个整数。 此时&#xff0c;你需要选定一个数字 X&#xff0c;使我们可以将整副牌…

伍六七带你学算法 进阶篇-排序算法

给定一个整数数组 nums&#xff0c;将该数组升序排列。 示例 1&#xff1a; 输入&#xff1a;[5,2,3,1] 输出&#xff1a;[1,2,3,5] 示例 2&#xff1a; 输入&#xff1a;[5,1,1,2,0,0] 输出&#xff1a;[0,0,1,1,2,5] 各排序算法解法如下&#xff1a; (如想要了解算法排序原理…

伍六七带你学算法 进阶篇-生命游戏

有趣的算法题–生命游戏 难度-中等 根据 百度百科 &#xff0c;生命游戏&#xff0c;简称为生命&#xff0c;是英国数学家约翰何顿康威在 1970 年发明的细胞自动机。 想要体验生命游戏的小伙伴可以到这里——>生命游戏 进入正题&#xff1a; 给定一个包含 m n 个格子的…

Linux下docker安装配置oracle,oracle创建用户并远程连接,实测可用!

最近在给同学弄毕业设计的数据库&#xff0c;因为oracle在个人电脑上极不稳定&#xff0c;所以他的电脑数据库崩溃了&#xff0c;这时候我就在docker上为他拉了一个oracle&#xff0c;解决了问题。 docker的安装共有以下几步&#xff0c;实测没问题&#xff0c;直接搬去永久可以…

plsql配置多数据源,想换哪个换哪个

现在的公司内部普遍使用plsql对数据库进行管理。而数据库非常多&#xff0c;从测试到线上环境数据库那么多&#xff0c;我们通常使用同一配置管理&#xff0c;便于切换。那么配置数据库连接就成为了很重要的一步。 1、安装plsql &#xff08;这里大家去下载安装一下&#xff0…

常见的几种网络抓包及协议分析工具

网络工程师必备技能-抓取网络数据。在本篇博客中,我们将集中记下几个问题进行探讨:Wireshark 是免费的抓取数据包、分析数据包的工具,兼容 Windows、Linux、Mac等主流平台。使用 wireshark 抓包需要的工具是:安装了 wireshark 的 PC。wireshark 抓包的范围是:抓取安装了 wireshark 的 PC 本机的网卡上流经的数据包。其中,网卡指的是 PC 上网使用的模块,常见的包括:以太网网卡、wifi 无线网卡,PC 分别使用它们用于连接以太网、wifi 无线网络。

一文搞懂网络OSI网络模型

在互联网技术里,有两件事最为重要,一个是TCP/IP协议,它是万物互联的事实标准;另一个是Linux操作系统,它是推动互联网技术走向繁荣的基石。在网络编程中最重要的模型便是OSI七层网络模型和TCP/IP四层网络模型七层模型,也称为OSI(Open System Interconnection)参考模型,是国际标准化(ISO)指定的一个用于计算机或通信系统间互联的标准体系。建立七层模型的主要目的是为解决各种网络互联时遇到的兼容性问题。

简单两步,spring aop上手即用即会

面向切面思想在于它的干净&#xff0c;对逻辑代码没有任何侵入性&#xff0c;只需要在想要切入的方法或者类之上加上自定义的注解即可。 首先&#xff0c;就是自定义一个注解&#xff1a; //这里我们定义一个名为 MyPointer 的注解 Documented Retention(RetentionPolicy.RUNTI…

手动将jar包导入pom依赖,让jar包适配本地maven项目

前言&#xff1a; Oracle对maven很久没有更新依赖&#xff0c;虽然19年更新了一版&#xff0c;但pom引入一直有错误。 我用的是oralce 12的依赖&#xff0c;虽然有jar包&#xff0c;但是依赖和pom没有适配&#xff0c;项目打包的时候还要去中央仓库去下载&#xff0c;而中央仓库…

浏览器兼容video视频播放的多种方法&视频在浏览器播放格式,视频浏览器播放格式演示

对于老版本的IE可以通过HTML5shiv来使不支持HTML5的浏览器支持HTML新标签video和audio标签。主要解决HTML5提出的新的元素不被IE6/IE7/IE8识别,这些新元素不能作为父节点包裹子元素,且不能应用CSS样式。让CSS 样式应用在未知元素只需执行 document.createElement(elementName) 即可实现。html5shiv的工作原理也就是基于此。

Linux通过端口号杀死指定进程

前言&#xff1a; 我们在服务器上升级项目的时候&#xff0c;需要将原来的项目停止&#xff0c;然后启动新的项目。 这时候我们只知道应用所占的端口号&#xff0c;如何将进程杀死呢&#xff1f; linux中杀进程时候&#xff0c;如果你是知道它所占用的端口号的话&#xff0c;可…

Linux/docker下oracle开启监听,开启自动启动

写在前头&#xff1a; 之前呢&#xff0c;使用docker安装了oracle&#xff0c;但它默认是会关闭的。使用了几天以后突然连接异常了&#xff0c;报的问题是oracle监听有问题了&#xff0c;我知道了是oracle服务自动关闭了&#xff0c;监听也跟着关了。所以我找了一些文章&#x…

手把手教你JavaEE的分页查询、分页展示,有了这个,你的项目又多了一个谈资

前言&#xff1a; 我们在写项目的时候&#xff0c;往往有一些项目的信息展示。而展示的数据量往往是很大的&#xff0c;这时候&#xff0c;加入一个分页的功能往往是最理想的选择。 先简单描述一下功能&#xff1a; 根据你的数据量和指定的页面展示数据条数&#xff0c;进行查…

一分钟带你了解什么是“复杂度” 算法上的O(1)、O(n)、O(logn) 这些都是什么❓❓

前言&#xff1a;在最开始学习编程的时候&#xff0c;打开数据结构的书&#xff0c;最显眼的就是排序算法&#xff0c;什么堆排序、希尔排序&#xff0c;然后旁边写着最坏复杂度、最优复杂度、平均复杂度&#xff0c;是一些O(n)、O(logn)、O(n)。这时候我脑子想起一首歌——大朋…

什么是LinkedList?什么时候使用它呢?Java LinkedList结构、用法及源码解析

前言&#xff1a;我们学习java时都知道ArrayList实现List接口&#xff0c;LinkedList也实现List接口&#xff0c;但我们平时用的时候LinkedList却很少被用到。那么&#xff0c;LinkedList什么时候该用到呢&#xff1f;内部又是如何实现的呢&#xff1f;本文对此进行详细说明&am…

Myeclipse中修改项目默认编码还是乱码?一步永久解决!

在myeclipse中修改默认编码后发现项目还是乱码&#xff1f; 点击Windows选择Preferences 如下图&#x1f447; 点击General->Content Types->text->选择你要修改的文件类型->选择你要修改的编码格式 &#xff08;比如我这里是jsp页面乱码&#xff09;如下图&#…

Myeclipse中项目没有代码错误提示,jsp页面无编译迹象?如何解决

在使用Myeclipse开发项目时&#xff0c;发现jsp页面中嵌入的java代码没有编译的迹象&#xff0c;错误的get方法没有报错&#xff0c;没有报错信息我们如何知道我们开发的内容是正确的呢&#xff1f; 接下来就演示一下如何解决&#x1f449; 第一步&#xff0c;点击Project 选择…

伍六七带你学算法 入门篇 ——最大子序和

力扣 53. 最大子序和 难度简单 给定一个整数数组 nums &#xff0c;找到一个具有最大和的连续子数组&#xff08;子数组最少包含一个元素&#xff09;&#xff0c;返回其最大和。 示例: 输入: [-2,1,-3,4,-1,2,1,-5,4], 输出: 6 解释: 连续子数组 [4,-1,2,1] 的和最大&#xf…

伍六七带你学算法 入门篇——最后一个单词的长度

难度 简单 给定一个仅包含大小写字母和空格 ’ ’ 的字符串 s&#xff0c;返回其最后一个单词的长度。如果字符串从左向右滚动显示&#xff0c;那么最后一个单词就是最后出现的单词。 如果不存在最后一个单词&#xff0c;请返回 0 。 说明&#xff1a;一个单词是指仅由字母组…

伍六七带你学算法 动态规划 ——不同路径

力扣 62. 不同路径 难度 中等 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为“Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为“Finish”&#xff09;。 问总共有多少条不…

大脑的漏洞:你是如何走向狭隘和顽固的?

但是,我们常常会切断这个链条,只记住最终的结论,忘记了支撑结论的一系列事实、论据、逻辑,从而,任由这个落单的、孤零零的「结论」不断飘摇,不断泛化和极端化。像我在之前的文章里,以及智识营里,都提出过一些比较颠覆性的观点,就经常能看到「难以置信」「感觉自己的世界被颠覆了」「我需要时间去理解和接受」的留言……大脑难以记住复杂的事实,所以,我们会倾向于把事实「压缩」成一个高密度的观点。例如:当你阅读我的文章时,一定不要只记住我给出的「根本原因」和「做法」,也要同时记住「这些原因是怎么来的」「这些做法背后的原理」。

伍六七带你学算法——被忽视的数学公式

中学时候学习那么多的数学&#xff0c;却没有人告诉我们这些数学公式我们以后会用到哪里&#xff1f;疑惑了十好几年&#xff0c;直到&#xff0c;你进入it行业&#xff0c;它的舞台来了&#xff01; 在力扣上有一道中度难度的题&#xff0c;题目是这样的&#x1f447; &#…

设置linux初始root密码

简单一步设置linux第一个root密码 sudo passwd root #输入当前账户密码 #输入准备设置的root密码 #确认密码如下所示&#xff1a;&#x1f447;