奇趣技术网 收藏本站
设为主页
商务合作
首页 新闻中心 行业动态 软件新闻 安全资讯 病毒预警 漏洞发布 操作系统 Dos Win9x Win2000 WinXP Win2003 WinVista Linux Unix
数据库 DB2 Access MSSQL MySQL Oracle Sybase 编程技术 ASP PHP JSP CGI/Perl XML .Net C/C++/C# VB VC Delphi Java 汇编
安全技术 安全教学 工具介绍 漏洞利用 病毒防范 入侵检测 防火墙 安全防范 汉化破解 攻击实例 加密解密 技术论坛
中华网络安全联盟 >> 程序开发 >> Java >> 漫谈Java程序的性能优化
程序开发
Asp
PHP
JSP
CGI/Perl
XML
.Net
C/C++/C#
Visual Basic
Visual C++
Delphi
Java
汇编语言
  • Tomcat5.0.28下AXIS完

  • JSP环境的配置过程(J

  • 用JAVA写一个日志类程

  • 实现Hibernate分页查询

  • Struts + Hibernate 代

  • Hibernate 使用外部 C

  • 利用Eclipse开发Hiber

  • Java开源项目Hibernat

  • 漫谈Java程序的性能优化
    字体:

    中华网络安全联盟    作者:佚名    来源:网络转载    时间:2006-3-21

    Java使得复杂应用的开发变得相对简单,毫无疑问,它的这种易用性对Java的大范围流行功不可没。然而,这种易用性实际上是一把双刃剑。一个设计良好的Java程序,性能表现往往不如一个同样设计良好的C++程序。在Java程序中,性能问题的大部分原因并不在于Java语言,而是在于程序本身。养成好的代码编写习惯非常重要,比如正确地、巧妙地运用java.lang.String类和java.util.Vector类,它能够显著地提高程序的性能。下面我们就来具体地分析一下这方面的问题。

      在java中,使用最频繁、同时也是滥用最多的一个类或许就是java.lang.String,它也是导致代码性能低下最主要的原因之一。请考虑下面这个例子:

    String s1 = "Testing String";
    String s2 = "Concatenation Performance";
    String s3 = s1 + " " + s2;

      几乎所有的Java程序员都知道上面的代码效率不高。那么,我们应该怎么办呢?也许可以试试下面这种代码:

    StringBuffer s = new StringBuffer();
    s.append("Testing String");
    s.append(" ");
    s.append("Concatenation Performance");
    String s3 = s.toString();

      这些代码会比第一个代码片段效率更高吗?答案是否定的。这里的代码实际上正是编译器编译第一个代码片段之后的结果。既然与使用多个独立的String对象相比,StringBuffer并没有使代码有任何效率上的提高,那为什么有那么多的Java书籍批评第一种方法、推荐使用第二种方法?

      第二个代码片段用到了StringBuffer类(编译器在第一个片段中也将使用StringBuffer类),我们来分析一下StringBuffer类的默认构造函数,下面是它的代码:

    public StringBuffer() { this(16); }

      默认构造函数预设了16个字符的缓存容量。现在我们再来看看StringBuffer类的append()方法:

    public synchronized StringBuffer append(String str) {
    if (str == null) {
    str = String.valueOf(str);
    }
    int len = str.length();
    int newcount = count + len;
    if (newcount > value.length) expandCapacity(newcount);
    str.getChars(0, len, value, count);
    count = newcount; return this;
    }

      append()方法首先计算字符串追加完成后的总长度,如果这个总长度大于StringBuffer的存储能力,append()方法调用私有的expandCapacity()方法。expandCapacity()方法在每次被调用时使StringBuffer存储能力加倍,并把现有的字符数组内容复制到新的存储空间。

      在第二个代码片段中(以及在第一个代码片段的编译结果中),由于字符串追加操作的最后结果是“Testing String Concatenation Performance”,它有40个字符,StringBuffer的存储能力必须扩展两次,从而导致了两次代价昂贵的复制操作。因此,我们至少有一点可以做得比编译器更好,这就是分配一个初始存储容量大于或者等于40个字符的StringBuffer,如下所示:

    StringBuffer s = new StringBuffer(45);
    s.append("Testing String");
    s.append(" ");
    s.append("Concatenation Performance");
    String s3 = s.toString();

      再考虑下面这个例子:

    String s = "";
    int sum = 0;
    for(int I=1; I<10; I++) {
    sum += I;
    s = s + "+" +I ;
    }
    s = s + "=" + sum;
    分析一下为何前面的代码比下面的代码效率低:

    StringBuffer sb = new StringBuffer();
    int sum = 0;
    for(int I=1;
    I<10; I++){
    sum + = I;
    sb.append(I).append("+");
    }
    String s = sb.append("=").append(sum).toString();

      原因就在于每个s = s + "+" + I操作都要创建并拆除一个StringBuffer对象以及一个String对象。这完全是一种浪费,而在第二个例子中我们避免了这种情况。

      我们再来看看另外一个常用的Java类??java.util.Vector。简单地说,一个Vector就是一个java.lang.Object实例的数组。Vector与数组相似,它的元素可以通过整数形式的索引访问。但是,Vector类型的对象在创建之后,对象的大小能够根据元素的增加或者删除而扩展、缩小。请考虑下面这个向Vector加入元素的例子:

    字体:
     
    设为主页 收藏本站 联系我们 友情连接 商务合作 网友留言
    Copyright©2006-2008 中华网络安全联盟 All rights reserved.