JAVA性能优化

周围经常有同学纠结于现有的java代码应当怎么优化才能达到更高的性能,当然有些时候这中间也包括我但那是极少数情况,与代码的优化相比也许我更热衷于代码结构的重构。高效但难于理解与思路清晰却效率一般相比也许我更倾向于后者,因为大多数时候良好的设计与清晰的编码几乎总是优于“优化的” 代码,那么我们为什么还要优化代码呢?也可以说什么时候代码才需要我们去优化呢?当我们看到代码的优化对设计有积极的影响或对性能有硬性的要求时我们才真正需要对代码进行优化。

那么我们步入正题,来说一些java代码性能优化的技巧:

1.创建对象不好:也许第一眼看到这条技巧人们会感觉很迷惑JAVA是面向对象的语言,为什么创建对象不好呢?那是因为过多的对象实例,尤其是短期对象会导致不好的性能。大量对象引起的频繁的年轻代垃圾收集会导致程序性能的急剧下降,那么什么叫年轻代呢,年轻代指的是那些小的,生命周期短的对象,而对于年轻代的垃圾收集算法往往都是几乎全部停止的,阻塞一切的。那也就意味着如果对性能要求较高的尽量减少对象的引入,因为那样会导致过多不必要的停顿,从而严重影响到程序的性能。

2.静态好:这一点对于拜读过《Thinking in java》的人们都应该知道其中的原理,如果一个方法能够定义成静态的那么就把它定义成静态的,因为静态方法不是虚的,所以执行的时候不会动态分派,这样能够适当提升程序运行速度除此之外与实例方法相比高级的VM更愿意内联静态方法。这也就使我们最常用的方法在执行时能够达到更高的效率,对于非内联的代码指令指针必须在指针更新之后指向下一条指令以便让处理器知道到什么位置去取得下一个指针,然而对于内联的代码只需在整个代码块执行完毕之后才需要更新指令指针,这也就是内联代码的优势所在。

3.表切换好,查找切换不好:这一点主要影响的是switch语句块,对于switch语句块标签值集中的语句块要比标签值分散的语句块执行效率要高。因为java中的siwtch有两种字节码,一种是tableswitch另一种是lookupswitch对于标签值集中的switch语句块采用tableswitch当去选择相应的标签时我们只需要把一个偏移量传入一个函数表中。然而标签值不集中的switch语句块就要根据标签值到所有的标签中一一查找比较才能找到相应的值:函数对进行执行。两者的效率差显而易见了吧。

4.方法越小越好:对于java程序的执行往往是很小的一部分代码占据了很大的执行之间,这句话的意思也就是说,java中的很多代码需要频繁的执行,那么java为了提高执行效率把一些常用的代码进行缓存,在需要时直接在缓存中读取,然而如果一个方法过大那么它将整个编译占据很大的缓存空间,然而缓存的大小是一定的,那么就使得一些真正常用的代码得不到缓存从而影响执行效率。

5.Exception用于异常:对于一些刚刚接触到java的人来说,往往把Exception当成Error。然而Exception的设计初中并不是表示错误而是异常,是程序的非正常运行环境,是可恢复的,因此在运用Exception时常用于程序在非正常运行环境中的流程控制,这种情况下会提示VM优化正常的路径。也许熟悉java中try/catch语句块的同学会对这一点体会比较深吧,底层的异常往往封装向上抛出到控制层进行捕捉处理然后确定执行的代码路径。

6.小心使用装饰器模式:熟悉设计模式的人们也许会对这个模式不陌生,利用这种模式能够动态的为对象添加职责,在设计的角度看这种模式是相当优秀的,能够解决很多问题,最常见的问题就是java中的io。然而使用装饰器模式的时候间接的额外开销很大,会对性能产生一定的影响。人们在日常中也许经常使用的装饰器往往是给一个对象添加装饰器,从而增加对象的职责,然而装饰器也是能够从一个对象上移除的,移除的方法往往是与异常相结合,在装饰器的方法中抛出一个异常,当异常条件成熟的时候对异常进行捕捉然后对装饰器进行删除,这也算是结合异常对程序的执行进行控制吧。

7.对类进行instanceof操作更快:我记得当初刚接触java的时候,上课老师说过java中使用instanceof不好,因为它不是面向对象的,用了的话代码就不好了,大概就是这么个意思,不过在日后的变成过程中发现有些时候instansof是必不可少的,也没有使代码变坏的味道,不像老师说的那么严重。在应用instanceof的情况一般会有两种,一种是面对继承链的,另一种是面对接口的,对于面向继承链的类型判断后台的操作只需要做一次减法和一个数组查找,也就是相当于一次随机读取,然而对于接口的需要做的却是一次数组搜索,性能差距可想而知。

8.最小程度的使用同步代码快:对于这一点经常编写多线程程序的同学们也许会感触很深,过于庞大的同步代码快会严重阻塞程序的执行,降低程序的执行效率,我们经常的做法是把不涉及临界区域操作的语句移动到同步代码块之外缩小同步代码快的大小,也许我们还有另外的思路,比如volatile的引用具体原理可以参考java内存模型,或者在事物层次进行原子操作的控制。

9.小心外部的库:我们在平时的项目中往往会引用到外部的库,然而有时我们只需要其中的一小部分功能,那么过多这样的引用会导致我们程序不必要的臃肿,那么最好的办法就是对于任务简单,但是关系到程序关键部分的功能不如我们自己去实现从而避免对外部库的依赖,同时又能够根据自身项目的具体情况进行优化。

总之,优化始终第二位的,良好的设计与清晰的代码是第一位的。请记住,优化的第一准则是:不要优化,优化的第二准则(对于专家)同样是不要优化。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值