代码优化

浅谈程序优化

荒凉一梦 提交于 2020-01-22 19:15:24
   当初在学校实验室的时候,常常写一个算法,让程序跑着四处去晃荡一下回来,结果也就出来了。可工作后,算法效率似乎重要多了,毕竟得真枪实弹放到产品中,卖给客户的;很多时候,还要搞到嵌入式设备里实时地跑,这么一来真是压力山大了 ~~~ 。这期间,对于程序优化也算略知皮毛,下面就针对这个问题讲讲。   首先说明一下,这里说的程序优化是指程序效率的优化。一般来说,程序优化主要是以下三个步骤:    1. 算法优化    2. 代码优化    3. 指令优化 算法优化   算法上的优化是必须首要考虑的,也是最重要的一步。一般我们需要分析算法的时间复杂度,即处理时间与输入数据规模的一个量级关系,一个优秀的算法可以将算法复杂度降低若干量级,那么同样的实现,其平均耗时一般会比其他复杂度高的算法少(这里不代表任意输入都更快)。   比如说排序算法,快速排序的时间复杂度为O(nlogn),而插入排序的时间复杂度为O(n*n),那么在统计意义下,快速排序会比插入排序快,而且随着输入序列长度n的增加,两者耗时相差会越来越大。但是,假如输入数据本身就已经是升序(或降序),那么实际运行下来,快速排序会更慢。   因此,实现同样的功能,优先选择时间复杂度低的算法。比如对图像进行二维可分的高斯卷积,图像尺寸为MxN,卷积核尺寸为PxQ,那么     直接按卷积的定义计算,时间复杂度为O(MNPQ)    

Dubbo 2.7.5在线程模型上的优化

ぃ、小莉子 提交于 2020-01-21 04:05:09
这是why技术的第30篇原创文章 这可能是全网第一篇解析Dubbo 2.7.5里程碑版本中的改进点之一:客户端线程模型优化的文章。 先劝退:文本共计8190字,54张图。阅读之前需要对Dubbo相关知识点有一定的基础。内容比较硬核,劝君谨慎阅读。 读不下去不要紧,我写的真的很辛苦的,帮忙拉到最后点个赞吧。 本文目录 第一节:官方发布 本小节主要是通过官方发布的一篇名为《Dubbo 发布里程碑版本,性能提升30%》的文章作为引子,引出本文所要分享的内容:客户端线程模型优化。 第二节:官网上的介绍 在介绍优化后的消费端线程模型之前,先简单的介绍一下Dubbo的线程模型是什么。同时发现官方文档对于该部分的介绍十分简略,所以结合代码对其进行补充说明。 第三节:2.7.5版本之前的线程模型的问题 通过一个issue串联本小节,道出并分析一些消费端应用,当面临需要消费大量服务且并发数比较大的大流量场景时(典型如网关类场景),经常会出现消费端线程数分配过多的问题。 第四节:thredless是什么 通过第三节引出了新版本的解决方案,thredless。并对其进行一个简单的介绍。 第五节:场景复现 由于条件有限,场景复现起来比较麻烦,但是我在issues#890中发现了一个很好的终结,所以我搬过来了。 第六节:新旧线程模型对比 本小节通过对比新老线程模型的调用流程,并对比2.7.4.1版本和2.7

[你必须知道的.NET]第三十五回,判断dll是debug还是release,这是个问题

拥有回忆 提交于 2020-01-21 02:17:07
问题的提出 晚上翻着群里的聊天,发现一个有趣的问题:如何通过编码方式来判断一个dll或者exe为debug build还是release build?由于没有太多的讨论,所以我只好自己找点儿办法,试图解决这个问题,为夜生活带点刺激。于是,便有了本文的探索和分析。 当然,为了充分的调动起大家的主意,省去不必要的google操作,我觉得有必要对Debug和Release两种模式的异同进行一点提纲挈领式的分析,从而为接下来的解决方案打好基础。 Debug & Release 我们应用Visual Studio对代码文件进行F5操作(Build)时,实际是发生了一系列语法检查、词法检查和编译过程,通常情况下我们有两种Build模式,这就是常说的Debug Build和Release Build。望文知意,Debug Build模式通常应用于开发时,便于调试反馈;而Release Build则应用于部署时,这是因为Release模式下,编译器做了很多的优化操作(代码冗余、循环优化等),省去了对调试信息的记录。因此,两种Build模式是各不相同的,我们对其二者进行一点总结如下: Debug用于开发时,Release用于部署时。 Debug模式下,将产生pdb文件,用于保存状态信息和调试信息;Release模式下,不产生调试信息,也没有pdb文件。 Debug模式下,System

Baidu Apollo代码解析之Open Space Planner中的平滑优化

社会主义新天地 提交于 2020-01-19 19:53:08
大家好,我已经把CSDN上的博客迁移到了知乎上,欢迎大家在知乎关注我的专栏 慢慢悠悠小马车 ( https://zhuanlan.zhihu.com/c_1132958996826546176 ) 。以后,我会把日常的思考放在CSDN上,梳理过的精华文章放在知乎上,希望大家可以多多交流,互相学习。 目录 1、Hybrid A*和平滑优化的效果对比 2、Optimization Smoothing的调用 3、添加障碍物 1、Hybrid A*和平滑优化的效果对比 如我在 之前的博文 所述,Baidu Apollo 先使用Hybrid A*算法规划了一条粗糙无碰的轨迹,然后使用优化方法来平滑这条轨迹。我搭建了一个非常简单的停车场景,使用Hybrid A*规划的轨迹和平滑后的轨迹分别如下所示,深绿色为粗糙轨迹,浅绿色为平滑轨迹。单纯看path的形状,有时“平滑”会不太明显,但是看平滑后的速度v、朝向phi、转向角steer、加速度a,会更明显些。(注:图1-2与图3-4并不是对应的,此处仅仅是对比优化前后的效果) 图0 Hybrid A*输出的路径有很多转折 图1 Hybrid A* 输出的路径 图2 Optimization smoothing 输出的路径 图3 Hybrid A* 输出路径的朝向角 图4 优化后的路径的朝向角 从图2可以看到,Hybrid A

web前端 | 博客(四)优化代码

你说的曾经没有我的故事 提交于 2020-01-18 09:37:59
优化代码 分离app.js中的功能代码 由于只想在app.js中引入一些模块,做一些基础的配置工作,并不想把实现具体功能的代码写在这个文件中,所以要把功能代码从app.js文件中分离出去。 例如,把 app.use('/admin', 请求处理函数) 中app.use()保留,而把第二个参数,即请求处理函数,分离出去。 在blog文件夹下新建一个middleware的文件夹,再在这个文件夹之下新建一个loginGuard.js,存放登录拦截的代码。 把请求处理函数剪切进去,并起名 const guard = 挪进来部分 。 此时loginGuard.js是一个模块,在默认情况下,模块外部是访问不到的。所以要把这个方法通过 module.exports = guard; 暴露出去。 在外部引入这个模块的时候,会直接得到guard这个方法。所以,app.js中,直接 app.use('/admin', require('./middleware/loginGuard')); 可以看到,未登录状态下登录拦截功能依然奏效,说明代码没有问题。 优化admin.js中的代码 在一个真实的项目中,路由有非常多,如果把所有的代码都放置在admin.js中,那么这个文件就会变得非常非常的庞大。所以接下来要继续对当前文件进行优化。 把admin.js变成路由列表,把路由处理代码,即路由方法的第二个参数

Java代码优化篇

允我心安 提交于 2020-01-17 06:30:58
1.需要 Map 的主键和取值时,应该迭代 entrySet() 当循环中只需要 Map 的主键时,迭代 keySet() 是正确的。但是,当需要主键和取值时,迭代 entrySet() 才是更高效的做法,比先迭代 keySet() 后再去 get 取值性能更佳。 Map < String , String > map = . . . ; for ( Map . Entry < String , String > entry : map . entrySet ( ) ) { String key = entry . getKey ( ) ; String value = entry . getValue ( ) ; . . . } 2.应该使用Collection.isEmpty()检测空 使用 Collection.size() 来检测空逻辑上没有问题,但是使用 Collection.isEmpty()使得代码更易读,并且可以获得更好的性能。任何 Collection.isEmpty() 实现的时间复杂度都是 O(1) ,但是某些 Collection.size() 实现的时间复杂度可能是 O(n) 。 if ( collection . isEmpty ( ) ) { . . . } 3.集合初始化尽量指定大小 java 的集合类用起来十分方便,但是看源码可知

又一款 javascript 代码优化工具 UglifyJS

最后都变了- 提交于 2020-01-17 05:15:38
冒着被人骂的风险发来主页,要是我火星了。请无视我吧…… jquery 1.5 发布的时候 john resig 大神说 所用的代码优化程序从Google Closure切换到UglifyJS,新工具的压缩效果非常令人满 意。 UglifyJS 是一个服务端node.js的压缩程序。据说很黄很暴力…… 我测试了一下压缩率确实比较高。 所以值得写篇文章推荐下。 -------------------------------------------------------------------------------------------- 你也可以尝试一下在线版的Uglifyjs: https://ganquan.info/webkit/ -------------------------------------------------------------------------------------------- 如果你对 uglifyjs 有兴趣可以按照以下安装方式进行安装。 1. 安装 node.js 环境 (这个不用我教了吧,网上教程一大堆哦。) 2. 进入 https://github.com/mishoo/UglifyJS 右上角 “Download” ZIP下载整个包。 3. 解压打开 UglifyJS/bin/uglifyjs 4. 找到 global.sys

【转】性能优化 = 改改代码?

て烟熏妆下的殇ゞ 提交于 2020-01-16 09:41:29
原文地址:https://mp.weixin.qq.com/s/jf9_8KADzNtkDyoxE8-HBg 上了一定规模的系统,特别是To C的系统,性能优化或多或少都会被逼着去做一下。否则,系统便无法支撑业务的发展,技术成了拖后腿,不是引领业务了。 一旦线上出现了性能问题,就会很棘手。因为它和业务功能上的Bug不同,后者的分析和解决思路更清晰,只要日志记录到位,沿着一条已知的业务逻辑线,很容易就能找到问题根源。 而性能问题就会复杂的多,导致的因素有很多,甚至会是多种因素共同作用下的结果。比如,代码质量低下、业务发展太快、架构设计不合理等等。 而且一般情况下,性能问题处理起来比较耗时,涉及到的分析链路可能会很长,特别是自己小组之外的上下游系统,很多人不愿意干,或者说有心无力。最多采用一些临时性的补救手段,碰碰运气。比如,扩容增加机器、重启大招、……。 有些临时性的补救措施,有时候不但不能解决问题,还会埋下新的隐患。 比如,从表象上看到某个程序因为给的资源不足导致产生性能问题。临时增加更多资源给它,可能从表面上看,问题是解决了。但是实则可能是因为程序内部对资源的使用上存在不合理的地方,增加资源只是延缓问题发作的时间,而且还可能会侵占其它程序的运行资源。 为了避免陷入如此的窘境,我们应当尽量提前进行性能优化,未雨绸缪。甚至最好是将它作为一个周期性的工作来进行。

策略模式之if else代码优化

梦想与她 提交于 2020-01-16 00:31:48
一、概念   策略模式的用意是针对一组算法,将每一个算法封装到具有共同接口的独立类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。 if else使用 if ( pageLevel = "1" ) { // 发送get请求 } else if ( pageLevel = "2" ) { // 发送post请求 } else { // }   这种if else代码块中,代码很难维护也很也不够美观,那么我们可以使用策略模式来处理这种情况。 二、案例   简单来讲就是定义一个接口,然后有多个实现类,每种实现类封装了一种行为。然后根据条件的不同选择不同的实现类。 抽象业务接口 public interface SendRequestCenter { public abstract void solve ( String param ) ; public abstract String [ ] supports ( ) ; } 接口实现类,举例:一个发送get请求,一个发送post请求 import org . springframework . stereotype . Component ; @Component public class SendPostRequestSolver implements SendRequestCenter {

C中的volatile用法

梦想的初衷 提交于 2020-01-11 07:57:52
C中的volatile用法 volatile 影响编译器编译的结果,指出,volatile 变量是随时可能发生变化的,与volatile变量有关的运算,不要进行编译优化,以免出错,(VC++ 在产生release版可执行码时会进行编译优化,加volatile关键字的变量有关的运算,将不进行编译优化。)。 例如: volatile int i=10; int j = i; ... int k = i; volatile 告诉编译器i是随时可能发生变化的,每次使用它的时候必须从i的地址中读取,因而编译器生成的可执行码会重新从i的地址读取数据放在k中。 而 优化做法是,由于编译器发现两次从i读数据的代码之间的代码没有对i进行过操作,它会自动把上次读的数据放在k中。而不是重新从i里面读。这样以来,如果 i是一个寄存器变量或者表示一个端口数据就容易出错,所以说volatile可以保证对特殊地址的稳定访问,不会出错。 /********************** 一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子: 1) 并行设备的硬件寄存器(如:状态寄存器) 2)