`

JAVA中字符串连接效率的测试

    博客分类:
  • Java
阅读更多
比较JAVA中String ,StringBuffer,SrtingBuilder三个对象连接字符串的效率。

我们经常都听有经验的人说,避免使用String通过“+”连接字符串,特
别是连接的次数很多的时候,一定要用StringBuffer。

比较下究竟谁的效率高,下边是测试代码,可直接运行:
package cn.com.test;

public class TestStringConnectTime {
   
    //连接时间的设定
    private final int n = 20000;
   
    public static void main(String[] args){
       TestStringConnectTime test = new TestStringConnectTime ();
       test.testStringTime();
       test.testStringBufferTime();
       test.testStringBuilderTime();
    }
   
    /**
     *测试String连接字符串的时间
     */
    public void testStringTime(){
       long start = System.currentTimeMillis();
       String a = "";
       for(int k=0;k<n;k++ ){
           a += "_" + k;
       }
       long end = System.currentTimeMillis();
       long time = end - start;
       System.out.println("String time:" + time);
    }
   
    /**
     *测试StringBuffer连接字符串的时间
     */
    public void testStringBufferTime(){
       long start = System.currentTimeMillis();
       StringBuffer b = new StringBuffer() ;
       for(int k=0;k<n;k++ ){
           b.append( "_" + k );
       }
       long end = System.currentTimeMillis();
       long time = end - start;
       System.out.println("StringBuffer time:" + time);
    }
   
    /**
     *测试StringBuilder连接字符串的时间
     */
    public void testStringBuilderTime(){
       long start = System.currentTimeMillis();
       StringBuilder c = new StringBuilder() ;
       for(int k=0;k<n;k++ ){
           c.append( "_" + k );
       }
       long end = System.currentTimeMillis();
       long time = end - start;
       System.out.println("StringBuilder time:" + time);
    }

}


分别测试了n=10,100,500,1000,5000,10000,20000的时候,三个对象连接字符串所花费的时间,
做了个简单统计,得到如下数据:

连接次数(n) 所需时间(单位毫秒)
      String StringBuffer StringBuilder
10       0        0           0
100      0        0           0
500      31       16          0
1000     63       31          16
5000     781      63          47
10000    7547     63          62
20000    62984    94          63

由上边的图表结果对比,可以清楚的看出,为什么大家都鼓励用StringBuffer连接字符串了。在连接次数少
的情况下,String的低效率表现并不是很突出,但是一旦连接次数多的时候,性能影响是很大的,String进
行2万次字符串的连接,大约需要1分钟时间,而StringBuffer只需要94毫秒,相差接近500倍以上。而
StringBuffer和StringBuilder差别并不大,StringBuilder比StringBuffer稍微快点,我想是因为StringBuffer
是线程序安全的,StringBuilder不是线程序安全的,所以StringBuffer稍微慢点。

但是为什么String如此慢呢,分析以下代码
String result="";
result+="ok";
这段代码性能很低,原因是java中的String类不可变的(immutable),
通过使用javap工具我们可以知道其实上面的代码在编译成字节码的时候等同的源代码是:
String result="";
StringBuffer temp=new StringBuffer();
temp.append(result);
temp.append("ok");
result=temp.toString();
短短的两个语句怎么呢变成这么多呢?问题的原因就在String类的不可变性上。

所以,如果你对字符串中的内容经常进行操作,特别是内容要修改时,那么使用StringBuffer,如果最后
需要String,那么使用StringBuffer的toString()方法好了。但是 StringBuilder 的实例用于多个线程是不安
全的。如果需要这样的同步,则建议使用 StringBuffer,因为StringBuffer是线程安全的。在大多数非多
线程的开发中,为了提高效率,可以采用StringBuilder代替StringBuffer,速度更快。

补1:
    public static String concat1(String s1, String s2, String s3, String s4, String s5, String s6) {
        String result = "";
        result += s1;
        result += s2;
        result += s3;
        result += s4;
        result += s5;
        result += s6;
        return result;
    }

    public static String concat2(String s1, String s2, String s3, String s4, String s5, String s6) {
        StringBuffer result = new StringBuffer();
        result.append(s1);
        result.append(s2);
        result.append(s3);
        result.append(s4);
        result.append(s5);
        result.append(s6);
        return result.toString();
    }

    public static String concat3(String s1, String s2, String s3, String s4, String s5, String s6) {
        return new StringBuffer(s1.length() + s2.length() + s3.length() + s4.length() + s5.length() + s6.length())
                .append(s1).append(s2).append(s3).append(s4).append(s5).append(s6).toString();
    }

    public static String concat4(String s1, String s2, String s3, String s4, String s5, String s6) {
        return s1 + s2 + s3 + s4 + s5 + s6;
    }

    public static String concat5(String s1, String s2, String s3, String s4, String s5, String s6) {
        return new StringBuilder(s1.length() + s2.length() + s3.length() + s4.length() + s5.length() + s6.length())
                .append(s1).append(s2).append(s3).append(s4).append(s5).append(s6).toString();
    }

第一种写法是最土的写法,也最累赘,事实上看到这样的代码我都会有点头疼。
看过《Effective Java》的朋友都知道用StringBuffer吧,用第二种写法的人应该也不少。
第4种写法当然最简捷,最优美的了,就是不知道性能怎么样。
Java 5里加了个StringBuilder类,与StringBuffer功能一样,就是没有同步,
所有用StringBuilder代替StringBuffer肯定对性能有好处,这样就产生的第5种写法。

还是做个测试有说服力。我的机器上同时装了JDK 5和JDK 6,两个都测了一下。
执行每个函数10000000次(输入的每个参数都是"a"),各种写法用时如下,单位毫秒:

JDK 5:
concat1: 13776
concat2: 5081
concat3: 4944
concat4: 4202
concat5: 4047

JDK 6:
concat1: 11801
concat2: 3930
concat3: 3976
concat4: 3353
concat5: 3440

可以看出第1种写法果然最慢,第二种写法由于用了StringBuffer,快了很多。
奇怪的是第4种写法竟然也很快,比用StringBuffer还快,怎么回事?
其实如果你调试过字符串连接的执行过程就会知道当用第4种写法时Java会自动使用StringBuilder.append()函数来进行连接。
所以最简捷的第4种写法已经够快了。
在JDK 5里,第5种写法最快,因为在创建StringBuilder的时候预先计算了总长度,消除了内存重分配。
不过没有必要这么写,JDK 6里已经为第4种写法做了更好的优化,第5种写法反而慢了。
分享到:
评论

相关推荐

    java字符串连接效率测试代码

    用于测试java字符串几种连接方式的效率,主要包括四类对比测试:1,StringBuffer连接,2,String的Format连接,3,String相加连接,4,StringBuffer的append串起来连接。测试结果如下: String Buffer: 580ms String...

    字符串连接方面测试时间

    这一主题对于理解不同字符串连接方式的性能优劣至关重要,尤其是当涉及到大量数据处理或高并发场景时,选择合适的字符串连接方式可以显著提高程序的运行效率。 ### 描述解析:“字符串连接时间测试” 描述部分重复...

    JAVA的字符串拼接[参照].pdf

    2. **String.concat(String str)**: 这是`String`类提供的一个方法,它接受一个字符串参数并返回一个新的字符串,将当前字符串与参数字符串连接起来。尽管比`+`操作符稍微高效,但在循环中大量使用仍然会导致性能...

    Android C、Java、JNI效率测试结果.doc

    这个文档描述了 Android G1 环境中,C、Java、JNI 调用(C 调 Java、Java 调 C)基本运算、方法调用、字符串连接的效率测试结果。 一、JNI 调用效率测试 在 Android G1 环境中,JNI 调用效率测试结果表明,无论是 ...

    Java字符串加密实例

    总之,Java中的字符串加密涉及到多种哈希和加密算法,它们各有优缺点。开发者应根据需求选择合适的算法,并遵循最佳实践,如使用加盐的哈希、强密钥管理和定期更新加密策略,以提高系统的安全性。

    java中拼接字符串的5种方法效率对比

    Java 中的 String 类提供了 concat 方法,可以将两个字符串连接起来。但是,这种方法的效率也不高,因为每次连接都会生成一个新的字符串对象。 第三种方法:使用 StringBuilder StringBuilder 是 Java 中的一个可变...

    JAVA常见字符串函数.doc

    4. concat(String str) 函数:该函数用于将指定字符串连接到当前字符串的结尾。例如,String str="Hello,World!"; System.out.println(str.concat("ok")); 结果Hello,World!ok。 5. copyValueOf(char[] ch,int ...

    JAVA字符串及习题[归类].pdf

    Java字符串在编程中扮演着重要角色,它们是不可变的对象,这意味着一旦创建,就不能更改其内容。本资料主要涵盖了字符串的比较、转化以及操作运算符的相关知识点。 1. 字符串的比较: Java中提供了两种主要的字符...

    java字符串拼接与性能分析详解

    Java字符串拼接是编程中常见的操作,特别是在处理大量数据或者构建复杂的输出时。然而,不同的字符串拼接方式在性能上存在显著差异。本篇文章将深入探讨Java中的字符串拼接技术,以及它们对程序效率的影响。 首先,...

    用JAVA和UDP实现字符串的发送和接收

    在本文中,我们将深入探讨如何使用Java编程语言和用户数据报协议(UDP)来实现字符串的发送和接收。首先,我们需要了解UDP的基本概念。UDP是一种无连接的、不可靠的传输层协议,它不保证数据包的顺序或完整性,但...

    温故知新——JavaScript中的字符串连接问题最全总结(推荐)

    在JavaScript中,字符串连接是一个常见的操作,但在处理大量字符串连接时,性能问题就显得尤为重要。这是因为JavaScript中的字符串是不可变的,这意味着每次进行字符串连接,实际上都会创建一个新的字符串对象来存储...

    字符串考试.zip

    本次"字符串考试"的主题很可能是一场针对编程中字符串处理能力的测试。在这个压缩包中,可能包含了各种题目、代码示例或者练习,帮助我们深入理解和掌握字符串操作的相关知识。 字符串的处理涵盖了许多方面,以下是...

    TestStringAndStringBuilder.rar 字符串优化

    这种机制虽然确保了线程安全性,但在大量字符串拼接操作时,频繁的对象创建会导致性能下降,尤其是当循环中进行字符串连接时。 相对地,`StringBuilder`类是可变的,它提供了一个可变的字符序列。在`StringBuilder`...

    字符串的展开(洛谷-P1098).rar

    1. **字符串拼接**:将多个字符串连接成一个单一的字符串,这可能需要使用到循环或者字符串的`+`运算符。 2. **字符串反转**:对给定的字符串进行反转操作,例如使用双指针或者栈的数据结构来实现。 3. **子串查找...

    javascript 字符串连接的性能问题(多浏览器)

    在给出的代码示例中,作者通过创建一个`StringBuffer`类来模拟Java中的StringBuilder功能,以优化字符串连接。`StringBuffer`类包含一个字符串数组,并提供了`append`方法用于添加字符串,以及`toString`方法用于将...

    mysql,sqlserver,oracle,java连接池,连接程序

    Oracle数据库的连接池配置则需要用到ojdbc驱动,其连接字符串格式为`jdbc:oracle:thin:@&lt;host&gt;:&lt;port&gt;:&lt;service_name&gt;`。Oracle的连接池配置通常还需要设置SID或Service Name,以及其他特定的连接属性。 在Java中,...

    数据库连接测试及数据的查询

    连接字符串是一个包含所有必要信息的文本字符串,例如: ```sql Server=myServerAddress;Database=myDataBase;User Id=myUsername;Password=myPassword; ``` 这里,`myServerAddress`是数据库服务器地址,`...

    ZIFUCHUAN.zip_字符串反转

    在编程面试中,字符串反转是一个常见的测试点,考察应聘者的编程思维和基础功底。 "ZIFUCHUAN"这个文件名可能是某种编码或者谜题,也可能代表了实现字符串反转的一种独特方式。由于没有具体的代码可供分析,我们...

    字符串使用情况查询,类型和内容可选

    总之,"字符串使用情况查询"工具是提高开发效率的重要辅助,它简化了字符串的查找过程,使得在大量代码中定位特定字符串变得轻而易举。无论是在日常编码、代码审查还是项目维护阶段,这样的工具都能发挥巨大作用,...

Global site tag (gtag.js) - Google Analytics