|
精华帖 (0) :: 良好帖 (0) :: 新手帖 (15) :: 隐藏帖 (0)
|
|
|---|---|
| 作者 | 正文 |
|
最后更新时间:2007-11-27 关键字: java
每一种语言都有其自身的特点,只有掌握了其自身的特点,才能用它编写出高效的程序。下面就我个人实践所知谈谈javaSE方面的性能问题,
javaEE方面的性能暂不讨论,要是时间可以再写一javaEE方面的性能问题的帖子。 1, 尽量不要使用+号来连接字符串。 2, 对小数据int的Integer封装,尽量的使用Integer.valueOf()创建,而不要使用new来创建。因为Integer类缓存了从-128到256个 状态的Integer。 3, 对Boolean类,要用valueOf()或使用Boolean.TRUE或Boolean.FALSE来创建对象。我个人觉得对Boolean类用private构造函数,可能就会避免不好的使用Boolean类了。 4, 在设计类时应尽可能地避免在类的默认构造函数中创建,初始化大量的对象。 5, 合理的申请数组空间,如果数组中所保存的元素占用内存空间较大或数组本身长度较长的情况,我们釆用可以釆用软引用的技术来引用数组,以“提醒”JVM及时的回收垃圾内存,维护系统的稳定性。 6, 避免创建重复的对象,我们在编写一个方法的时候应该先考虑方法里的局部对象域能否改为private static final,从而避免创建重复的对象。 7, 把try/catch块放入循环体内,会极大的影响性能,如果编译JIT被关闭或者你所使用的一个不带JIT的JVM,性能会将下降21%之多! 8,StringBuffer的构造器会创建一个默认大小(通常是16)的字符数组。在使用中,如果超出这个大小,就会重新分配内存,创建一 个更大的数组,并将原先的数组复制过来,再丢弃旧的数组。在大多数情况下,你可以在创建StringBuffer的时候指定大小,这样 就避免了在容量不够的时候自动增长,以提高性能。 9, 使用Java NIO提高服务端程序的性能。 10,考虑用静态工厂方法替代构造函数。 11,在对大量的数组拷贝时,可以考虑用Arrays.copyOf()来拷贝。 12, 在并发的情况下,要合理的选择同步的策略,应该谨慎的控制synchronized块的大小,不可以将一个操作分解到多个synchronized 但也要尽量地从synchronized块中分离耗时的且不影响并发的操作。 13,要合理的选择集合框架,例如:ArrayList和LinkedList在某些不同的场合,其性能相差很大。对要做大量的插入时,LinkedList 的性能比ArrayList的性能好。对要做大量随机查找的时候用ArrayList的性能比用LinkedList的性能好。还有在不需要并发操作的 情况下,选择非线程安全的集合比线程安全的集合要好。如在非线程安全的要求下,选择ArrayList要比Vector好。 14,如果是想把数据封装成Double类型的,不要这样使用new Double("1.23"),而要应这样使用new Double(1.23),虽然二者都没有语法 的错误,也都能达到预期的结果,但其性能有着很大的差异。 15, 应尽量的通过缓冲流类来提高I/O操作效率,但也要合理的选择缓冲大小 。 呵呵,好了,今天就写到这吧,以后要是有时间再继续写。小弟我初学java,不对之地,欢迎大家指正,补遗。 声明:JavaEye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
|
|
| 返回顶楼 | |
|
最后更新时间:2007-11-21
Effective java?
|
|
| 返回顶楼 | |
|
最后更新时间:2007-11-22
呵呵,写得不错!
|
|
| 返回顶楼 | |
|
最后更新时间:2007-11-22
hahaha.写的可以!
|
|
| 返回顶楼 | |
|
最后更新时间:2007-11-22
14,不要在循环语句块中调用length()方法做为循环结束的条件。
15,如果字符串特别长,不要釆用charAt()一一的获取特定位置的字符,而应该调用toCharArray()方法转化为字符数组,然后通过数组 索引值获取指定位置的字符。 请问这两条是为什么? |
|
| 返回顶楼 | |
|
最后更新时间:2007-11-22
16,如果是想把数据封装成Double类型的,不要这样使用new Double("1.23"),而要应这样使用new Double(1.23),虽然二者都没有语法 的错误,也都能达到预期的结果,但其性能有着很大的差异。
使用 new Double("1.23") 比较好一些,原因是计算机有截断误差,采用new Double(1.23)时候精度可能不正确,这方面的信息可以参考java doc 这个问题可以推广一下,凡是希望采用浮点类型数据分装类(Float, Double, BigDecima)的时 尽量采用字符构造函数 |
|
| 返回顶楼 | |
|
最后更新时间:2007-11-22
只在面试时有用
|
|
| 返回顶楼 | |
|
最后更新时间:2007-11-22
danceflash 写道 14,不要在循环语句块中调用length()方法做为循环结束的条件。
15,如果字符串特别长,不要釆用charAt()一一的获取特定位置的字符,而应该调用toCharArray()方法转化为字符数组,然后通过数组 索引值获取指定位置的字符。 请问这两条是为什么? 14条的意思是不要这样使用 for(int i = 0 ; i < str.length();i++) 而要这样使用 int size = length(); for(int i = 0 ; i < size; i++) 15条是因为charAt()因为每次获取指定索引位置的字符都要引起新的检索过程。 |
|
| 返回顶楼 | |
|
最后更新时间:2007-11-22
mikewang 写道 16,如果是想把数据封装成Double类型的,不要这样使用new Double("1.23"),而要应这样使用new Double(1.23),虽然二者都没有语法 的错误,也都能达到预期的结果,但其性能有着很大的差异。
使用 new Double("1.23") 比较好一些,原因是计算机有截断误差,采用new Double(1.23)时候精度可能不正确,这方面的信息可以参考java doc 这个问题可以推广一下,凡是希望采用浮点类型数据分装类(Float, Double, BigDecima)的时 尽量采用字符构造函数 使用 new Double("1.23") 和 使用 new Double(1.23)二者的性能是不一样的。当然,这里就是说二者的性能不一样。因为,我做实验如下: public class DoubleTest{ public static void main(String[] args){ final int N = 100000; Double d; //字符串构造 long startTime = System.currentTimeMillis(); for(int i = 0; i < N; i++){ d = new Double("1.23"); } long endTime = System.currentTimeMillis(); System.out.println("字符串构造Double:" + (endTime - startTime)); //数字直接构造 startTime = System.currentTimeMillis(); for(int j = 0; j < N; j++){ d = new Double(1.23); } endTime = System.currentTimeMillis(); System.out.println("数字直接构造Double:"+(endTime - startTime)); } } 字符串构造Double:78 数字直接构造Double:0 这是在我机器上的数据。 |
|
| 返回顶楼 | |
|
最后更新时间:2008-07-09
第十四条:str.length是不计算的,没有性能问题的,大家可以自己看看String.java的源代码,我一开始还怀疑自己的理解不对,特意看了下,长度是有一个值专门缓存的,所以没有性能问题。
优化三原则: 第一:不要优化。 第二:不要优化。 第三:不要优化。 楼主中的不少优化其实是没有必要的。 除了刚才说的length以外,列举其他毫无必要的条目。 第一条,据我了解新版jdk跨行一样会优化的。 第四条,有些古老的类没办法的,可以像JDBC驱动那样,要求调用方先调一次Class.forName()可以确保初始化。 第六条,JDK 1.3+以上可以不考虑。 第十三条:实际使用中应该大力提倡LinkedList,并推荐是用迭代子遍历,尽量避免随机访问的需求,一般随机访问会用到HashMap。 第十五条:参考String.java的实现,本身就是数组,任何一本优化书都不会这么说的吧,我开始怀疑楼主参考的书的作者的忽悠程度了。 第十六条:各位同学们,企业计算很少碰到Double,大家赶快换成BigDecimal吧,Double和Float都会产生精度丢失的问题的。 |
|
| 返回顶楼 | |







