`

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

    博客分类:
  • java
阅读更多

http://xumiao900.iteye.com/blog/477778

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种写法反而慢了。
分享到:
评论
1 楼 weipeng1986 2014-04-08  
授人予鱼不如授人予鱼,我想问你的是你是怎么总结的。比如第四种情况,是根据了解java新特性的启发还是怎么?

相关推荐

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

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

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

    world 文档,描述了Android g1环境,C、Java、JNI调用(C调Java、Java调C)基本运算、方法调用、字符串连接的效率测试结果。

    Java之JDBC连接MySQL数据库实现增删改查(2018 使用Dao层实现 完美封装解决硬编码问题 使用预编译对象PreparedStatement)

    实现类 UserDaoImpl.java(实现增删改查功能 使用预编译对象PreparedStatement 安全、便捷不需要我们去拼接字符串,特别是字段很多的时候 同时效率比Statement更高 ) 测试类 UserDaoTest.java(做测试增删改查功能...

    JDBC连接MySQL数据库实现增删改查(Dao层实现 解决硬编码 配置连接池获得连接对象 )

    实现类 UserDaoImpl.java(实现增删改查功能 使用预编译对象PreparedStatement 安全、便捷不需要我们去拼接字符串,特别是字段很多的时候 同时效率比Statement更高 ) 测试类 UserDaoTest.java(做测试增删改查功能...

    JAVA面试题最全集

    使用StringBuffer类与String类进行字符串连接时有何区别? 57.调用Thread类的destroy()方法有什么后果? 58.多线程,用什么关键字修饰同步方法?stop()和suspend()方法为何不推荐使用? 59.使用socket建立客户端...

    Java课程设计报告书

    4. 程序测试(如程序代码、功能测试、可靠性测试和效率测试等)。 5. 设计小结(包括) 三、 课程设计题目: 1. 选做部分 1) 利用Socket编程制作一个简单的C/S应用。其中,Client端为GUI程序,用于...

    jdbc连接数据库的方式2

     此外,使用Statement对象也使得编写动态SQL命令更加简单,因为我们可以将字符串连接在一起,建立一个有效的SQL命令。因此,我认为,Statement对象可以使动态SQL命令的创建和执行变得更加简单。  4、利用helper...

    java 面试题 总结

    JAVA平台提供了两个类:String和StringBuffer,它们可以储存和操作字符串,即包含多个字符的字符数据。这个String类提供了数值不可改变的字符串。而这个StringBuffer类提供的字符串进行修改。当你知道字符数据要改变...

    根据表结构生成JavaBean,史上最强最专业的表结构转JavaBean的工具(第8版)

    3、移除XML字符串拼接工具,将该功能整合到了字符串格式化工具中。 4、调整字段设置界面,更方便使用。 5、修正使用自定义注释时生成JavaBean注释不对的Bug。 6、现在测试数据库连接能显示数据库的版本信息了。 ...

    根据表结构自动生成JavaBean,史上最强最专业的表结构转JavaBean的工具(第10版)

    3、增强字符串格式化工具,使得自动拼接字符串的应用场景更多。 4、测试数据库连接、生成Bean文件、精确匹配的更多等按钮都使用了异步线程进行处理, 这样界面不再会被卡住了,点了这些按钮以后还可以同时对界面...

    超级有影响力霸气的Java面试题大全文档

     JAVA平台提供了两个类:String和StringBuffer,它们可以储存和操作字符串,即包含多个字符的字符数据。这个String类提供了数值不可改变的字符串。而这个StringBuffer类提供的字符串进行修改。当你知道字符数据要...

    正则表达式

    /\s+java\s+/ //匹配字符串"java" ,并且该串前后可以有一个或多个空格. /[^"] * / //匹配零个或多个非引号字符. 正则表达式的复制字符 字符 含义 ________________________________________________________...

    根据表结构生成JavaBean,史上最强最专业的表结构转JavaBean的工具(第6版)

    一直以来把数据库的表转换成Entity或DTO都是一件让人头痛的事情,既浪费时间又很繁琐... 9、集成工具新增String字符串拼接工具,实现秒拼StringBuffer,再也不怕拼长长的SQL了。 10、集成工具新增XML字符串拼接工具。

    AndroidBase android 应用开发框架.zip

    如网络下载,多线程与线程池的管理,数据库ORM,图片缓存管理,图片文件下载上传,Http请求工具,SOAP工具类,异步Task,常用工具类(字符串,日期,文件处理,图片处理工具) 开发工具在软件开发生命周期中扮演着...

    基于J2EE框架的个人博客系统项目毕业设计论文(源码和论文)

    在管理页面中添加和删除友情连接。这样博友可以在自己空间中快速定位自己的关心的网站。这样还可以让网友看到自己的一些信息。友情链接及网页访问量统计显示:在博客的个人页面中还提供了推荐给普通网络用户的相关...

    Oracle9i的init.ora参数中文说明

    值范围: Oracle8i National Language Support Guide 中指定的任何有效的10 字节字符串。 默认值: 从 NLS_TERRITORY 中获得 nls_date_language: 说明: 指定拼写日期名, 月名和日期缩写词 (AM, PM, AD, BC) 的语言。...

    C++数据抽象和问题求解(第6版).[美]Frank M. Carrano(带详细书签).pdf

    6.2.2 识别语言中的字符串 199 6.3 栈在代数表达式中的应用 200 6.3.1 计算后缀表达式 201 6.3.2 中缀表达式与后缀表达式的等价转换 202 6.4 使用栈查找航班图 205 6.5 栈和递归的关系 212 C++片段3 异常 221 ...

    2005-2009软件设计师历年真题

     • 排序算法、查找算法、数值计算方法、字符串处理方法、数据压缩算法、递归算法、图的相关算法  • 算法与数据结构的关系、算法效率、算法设计、算法描述(流程图、伪代码、决策表)、算法的复杂性  2.计算机...

    PHP3程序设计

    3.4.7 字符串连接操作符 38 3.4.8 逻辑操作符 38 3.4.9 赋值操作符 40 3.5 总结 41 第4章 程序控制 43 4.1 表达式 43 4.1.1 简单表达式 43 4.1.2 有副作用的简单表达式 43 4.1.3 复杂表达式 44 4.2 语句 44 4.3 函数...

Global site tag (gtag.js) - Google Analytics