Java性能优化

作者:禅楼望月(http://www.cnblogs.com/yaoyinglong

注:里面的测试结果会因电脑配置的不同而有所差异!!!

1. 为一些集合定义初始化大小

List、Set、Map都会有有一个默认的初始化大小,但是这个值往往不够我们使用,这时候JVM便会申请更大的一块内存给集合,然后将原集合中的数据复制过来,最后原集合等待被作为垃圾而回收。可见扩容是一件比较费事的事情,所以最好能准确的估计你所需要的最佳大小。

[+]view code

public class PerformanceOptimization {

public static void main(String[] args) {

long start=new Date().getTime();

List<String> a=new ArrayList<String>();

for(int i=0; i<1000000; i++){

a.add("a");

}

long end=new Date().getTime();

System.out.println(end-start);//47

}

}

优化后:

[+]view code

public class PerformanceOptimization {

public static void main(String[] args) {

long start=new Date().getTime();

List<String> a=new ArrayList<String>(1000000);

for(int i=0; i<1000000; i++){

a.add("a");

}

long end=new Date().getTime();

System.out.println(end-start);//32

}

}

这样积少成多,效果还是挺可观的。

2. 复制数组的时候使用System.arraycopy来代替循环copy,它的效率更高更简洁。

[+]view code

public class PerformanceOptimization {

public static void main(String[] args) {

int[] array1 = new int [100];

for (int i = 0; i < array1.length; i++) {

array1 [i] = i;

}

int[] array2 = new int [100];

System.arraycopy(array1, 0, array2, 0, array1.length);

}

}

3. 避免不需要的instanceof操作

如果左边的对象的静态类型等于右边的,instanceof表达式返回永远为true。

[+]view code

public class Dog extends Uiso {

void method (Dog dog, Uiso u) {

Dog d = dog;

if (d instanceof Uiso) // always true.

System.out.println("dog is a uiso");

Uiso uiso = u;

if (uiso instanceof Object) // always true.

System.out.println("uiso is an object");

}

}

4. 避免不需要的造型操作

所有的类都是直接或者间接继承自object。同样,所有的子类也都隐含的“等于”其父类。那么,由子类造型至父类的操作就是不必要的了。如:

class dog extends unc

dog dog = new dog ();

unc animal = (unc)dog; // not necessary

object o = (object)dog; // not necessary

5. 如果只是查找单个字符的话,用charAt()代替startsWith

[+]view code

public class PerformanceOptimization {

public void method(String s) {

if (s.startsWith("a")) { // violation

// ...

}

}

}

将‘startsWith‘ 替换成‘charAt()‘

[+]view code

public class PerformanceOptimization {

public void method(String s) {

if ( ‘a‘==s.charAt(0)  ) {

// ...

}

}

}

6. 使用移位操作来代替‘a / b‘和‘a * b‘操作

"/"和"*"都是一个很“昂贵”的操作,使用移位操作将会更快更有效。

[+]view code

public class PerformanceOptimization {

public static final int num = 16;

public void calculate(int a) {

int div = a / 4;            // should be replaced with "a >> 2".

int div2 = a / 8;         // should be replaced with "a >> 3".

int temp = a / 3;       // 不能转换成位移操作

}

}

public class PerformanceOptimization {

public static final int num = 16;

public void calculate(int a) {

int mul = a * 4;            // should be replaced with "a << 2".

int mul2 = 8 * a;         // should be replaced with "a << 3".

int temp = a * 3;         // 不能转换成位移操作

}

}

注:除非是在一个非常大的循环内,性能非常重要,而且你很清楚你自己在做什么,方可使用这种方法。否则提高性能所带来的程序可读性的降低将是不合算的。

7. 不要在循环中调用synchronized (同步)方法

方法的同步需要消耗相当大的资源,在一个循环中调用它绝对不是一个好主意。

[+]view code

public class PerformanceOptimization {

public synchronized void method (Object o) {

}

private void test () {

for (int i = 0; i < vector.size(); i++) {

method (vector.elementAt(i));    // violation

}

}

private Vector vector = new Vector (5, 5);

}

更正:不要在循环体中调用同步方法,如果必须同步的话,推荐以下方式:

[+]view code

public class PerformanceOptimization {

public void method (Object o) {}

private void test () {

synchronized(this){//在一个同步块中执行非同步方法

for (int i = 0; i < vector.size(); i++) {

method (vector.elementAt(i));

}

}

}

private Vector vector = new Vector (5, 5);

}

8. 将try/catch块移出循环

把try/catch块放入循环体内,会极大的影响性能,如果编译jit被关闭或者你所使用的是一个不带jit的jvm,性能会将下降21%之多!

[+]view code

public class PerformanceOptimization {

void method (FileInputStream fis) {

for (int i = 0; i < 100; i++) {

try {                                      // violation

_sum += fis.read();

} catch (Exception e) {}

}

}

private int _sum;

}

9. 对于boolean值,避免不必要的等式判断

将一个boolean值与一个true比较是一个恒等操作(直接返回该boolean变量的值). 移走对于boolean的不必要操作至少会带来2个好处:

1)代码执行的更快 (生成的字节码少了5个字节);
2)代码也会更加干净。

[+]view code

public class PerformanceOptimization {

boolean method (String string) {

// return string.endsWith ("a") == true;   // violation

return string.endsWith ("a");

}

}

10. 对于常量字符串,用‘string‘ 代替 ‘stringbuffer‘

常量字符串并不需要动态改变长度。把stringbuffer换成string,如果确定这个string不会再变的话,这将会减少运行开销提高性能。

11. 用‘StringTokenizer‘ 代替 ‘indexof()‘ 和‘substring()‘

字符串的分析在很多应用中都是常见的。使用substring()来分析字符串容易导致java.lang.StringIndexOutOfBoundsException。而使用StringTokenizer类来分析字符串则会容易一些,效率也会高一些。

12. 使用三元运算表达式替代"if (cond) XXX; else XXX;" 结构。

13. 尽量不要在循环体中实例化变量

在循环体中实例化临时变量将会增加内存消耗

14. 尽可能的使用栈变量

如果一个变量需要经常访问,那么你就需要考虑这个变量的作用域了。static? local?还是实例变量?访问静态变量和实例变量将会比访问局部变量跑的路径要长的多。

[+]view code

public class PerformanceOptimization {

void getsum (int[] values) {

for (int i=0; i < values.length; i++) {

_sum += values[i];           // violation.

}

}

void getsum2 (int[] values) {

for (int i=0; i < values.length; i++) {

_staticsum += values[i];          // violation.

}

}

private int _sum;

private static int _staticsum;

}

更正:如果可能,请使用局部变量作为你经常访问的变量。可以按下面的方法来修改getsum()方法:

[+]view code

void getsum (int[] values) {

int sum = _sum;  // temporary local variable.

for (int i=0; i < values.length; i++) {

sum += values[i];

}

_sum = sum;

}

15. 与一个接口 进行instanceof操作

基于接口的设计通常是件好事,因为它允许有不同的实现,而又保持灵活。只要可能,对一个对象进行instanceof操作,以判断它是否某一接口要比是否某一个类要快。

16. 尽量减少对变量的重复计算

比如

for(int i=0;i<list.size();i++)

应修改为

for(int i=0,len=list.size();i<len;i++)

17. 考虑使用静态方法

如果你没有必要去访问对象的外部,那么就使你的方法成为静态方法。她会被更快地调用,因为她不需要一个虚拟函数导向表。这同时也是一个很好的实践,因为她告诉你如何区分方法的性质,调用这个方法不会改变对象的状态。

时间: 2024-10-27 13:40:46

Java性能优化的相关文章

Java性能优化技巧及实战

Java性能优化技巧及实战 关于Java代码的性能优化,是每个javaer都渴望掌握的本领,进而晋升为大牛的必经之路,但是对java的调优需要了解整个java的运行机制及底层调用细节,需要多看多读多写多试,并非一朝一夕之功.本文是近期笔者给公司员工内部做的一个培训,主要讲述在系统压测过程中出现的性能问题,以及如何在编码过程中提升代码的运行效率,需要掌握哪些实战技巧.片子里干货较多,也很具有实操性,因此发文出来,共享给大家(部分数据做了去除公司特征信息,见谅).(PS:由于原文是ppt,因此做了导

java性能优化技巧

一.通用篇 "通用篇"讨论的问题适合于大多数 Java应用. 1.1     new 1.1     new 11..11 不用 nneeww关键词创建类的实例 用new 关键词创建类的实例时,构造函数链中的所有构造函数都会被自动调用.但如 果一个对象实现了Cloneable 接口,我们可以调用它的clone()方法.clone()方法不会调用任 何类构造函数. 在使用设计模式(Design Pattern)的场合,如果用 Factory模式创建对象,则改用clone() 方法创建新的

JAVA性能优化的五种方式

一,JAVA性能优化之设计优化 设计优化处于性能优化手段的上层.它往往须要在软件开发之前进行.在软件开发之前,系统架构师应该就评估系统可能存在的各种潜在问题和技术难点,并给出合理的设计方案,因为软件设计和系统架构对软件总体设计质量有决定性的影响.所以,设计调优对系统的性能影响也是最大的,假设说,代码优化.JVM优化都是对系统微观层次的"量"的优化,那设计优化就是对系统"质"的优化. 设计优化的一大显著特征是:它能够规避某一个组件的性能问题,而是改良组件的实现;比方:

Java性能优化,不得不付诸实践的JVM

暂附贴图,详情稍后叙述,欢迎留言交流 图一.JVM知识体系(部分) 图二.通过jconsole监控jvm 图三.通过jvisualvm监控jvm Java性能优化,不得不付诸实践的JVM,布布扣,bubuko.com

Java 性能优化之 String 篇

原文:http://www.ibm.com/developerworks/cn/java/j-lo-optmizestring/ Java 性能优化之 String 篇 String 方法用于文本分析及大量字符串处理时会对内存性能造成不可低估的影响.我们在一个大文本数据分析的项目中(我们统计一个约 300MB 的 csv 文件中所有单词出现的次数)发现,用于存放结果的 Collection 占用了几百兆的内存,远远超出唯一单词总数 20000 个. 本文将通过分析 String 在 JVM 中的

java性能优化笔记(三)java程序优化

程序代码优化要点: 字符串优化:分析String源码,了解String常用方法,使用StringBuffer.StringBuilder. List.Map.Set优化:分析常用ArrayList.LinkedList.HashMap.TreeMap.LinkedHashMap.Set接口.集合常用方法优化. 使用NIO:Buffered.Channel操作和原理,使用零拷贝. 引用优化:强引用.弱引用.软引用.虚引用.WeekHashMap. 优化技巧:常用代码优化技巧.这里不一一罗列,请参考

java性能优化技巧二

之前整理过一篇java性能优化的博客,链接java性能优化一,今天补充几个 1. 谨慎对待Java的循环遍历 Java中的列表遍历可比它看起来要麻烦多了.就以下面两段代码为例: A: private final List<Bar> _bars; for(Bar bar : _bars) { //Do important stuff } B: private final List<Bar> _bars; for(int i = 0; i < _bars.size(); i++)

[原创]Java性能优化权威指南读书思维导图

[原创]Java性能优化权威指南读书思维导图 书名:Java性能优化权威指南 原书名:Java performance 作者: (美)Charlie Hunt    Binu John 译者: 柳飞 陆明刚 京东购书地址: http://item.jd.com/11407830.html 介绍:<Java性能优化权威指南>是Java应用性能调优的圣经,内容通俗易懂,介绍了大量的监控和测量工具,涉及各种硬件架构和操作系统.涵盖了如何构建实验.解释结果以及如何采取行动等技巧. 现在自己是越来越忙,

15分钟了解Java性能优化以及一切你想知道的(转)

15分钟了解Java性能优化以及一切你想知道的 http://blog.csdn.net/kwensen/article/details/17302371

工作之:Java性能优化之创建对象

1.Java 性能优化之创建对象对于每个java程序员都知道怎样创建对象,但是你知道怎样创建才能提高应用的性能呢?你知道创建对象的应用规则吗?(1).要尽量避免在循环体中创建对象.(2).尽量及时使对象符合垃圾回收标准.(3).不要采用过深的继承层次.(4).访问本地变量优于访问类中的变量.例如:Vector v=new Vector();for(int i=0; i<100;i++){Object obj=new Object(); }这样的写法大家都不陌生吧.可是这样会浪费大量的内存空间.正