Effective Java 第三版——63. 注意字符串链接的性能

Tips
书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code
注意,书中的有些代码里方法是基于Java 9 API中的,因此JDK 最好下载 JDK 9以上的版本。java

Effective Java, Third Edition

63. 注意字符串链接的性能

字符串链接操做符(+)是将几个字符串组合成一个字符串的便捷的方法。对于生成单行输出或构造一个小的、固定大小的对象的字符串表示形式,它是能够的,可是它不能伸缩。重复使用字符串链接运算符来链接n个字符串须要n的平方级的时间。这是因为字符串是不可变的这一事实致使的结果(条目 17)。当链接两个字符串时,须要复制这两个字符串的内容。git

例如,考虑这个方法,它经过为每一个项目重复链接一行来构造帐单语句的字符串表示:github

// Inappropriate use of string concatenation - Performs poorly!
public String statement() {
    String result = "";
    for (int i = 0; i < numItems(); i++)
        result += lineForItem(i);  // String concatenation
    return result;
}

若是项的数量很大,则该方法的性能很是糟糕。为了达到可接受的性能,使用StringBuilder代替String来存储正在构建的语句:数组

public String statement() {
    StringBuilder b = new StringBuilder(numItems() * LINE_WIDTH);
    for (int i = 0; i < numItems(); i++)
        b.append(lineForItem(i));
    return b.toString();
}

自Java 6以来,为了使字符串链接更快,已经作了大量工做,可是这两个方法在性能上的差别仍然很大:若是numItems返回100个元素,每一个lineForItem返回一个固定长度为80个字符串,那么在个人机器上运行,第二个方法的速度是第一个方法的6.5倍。因为第一种方法在项目数量上是平方级增加的,而第二种方法是线性的,因此随着项目数量的增长,性能差别会变得愈来愈大。注意,第二个方法预先分配了一个足够大的StringBuilder来保存整个结果,从而消除了自动增加的须要。即便使用默认大小的StringBuilder,它仍然比第一个方法快5.5倍。app

道理很简单:除非性能可有可无,不然不要使用字符串链接操做符组合多个字符串。而是使用StringBuilder的append方法。或者,使用字符数组,或者一次处理一个字符串,而不是把它们组合起来。性能

相关文章
相关标签/搜索