`

字符串连接效率测试:stringbuilder》stringbuffer》+ 【转:尽量使用StringBuilder和StringBuffer进行字符串连接】

 
阅读更多

前几天性能测试的时候发现一个web 端cpu出现骤降的问题,一直没有找到原因,起初怀疑是tomcat的线程数有关,后来有怀疑是跟数据库的响应时间太长有关系,后来都一一排除了。

之所以此问题比较难以定位主要是因为通过现有的监控工具无法获知和分析tomcat内部各个线程的占用资源的情况。

上周装了一下jprofiler,然后又重新进行了一次压力测试,终于找到了问题的根源:)

主要的资源消耗点是:字符串的拼接上。代码中时使用”+“来进行字符串连接的。

(ps:jprofiler监控的粒度很细,但是由于其本身运行占用的资源消耗量也很大,因此在进行性能测时不能用其作为监控工具,在分析问题方面还是蛮有用的;jconsole是java自带的监控工具,其在远程监控应用程序时,不会对程序的性能造成影响,但由于其监控的粒度还是有些粗,因此tomcat内部的资源占用情况还是无法进行分析的

 

 

JAVA中String ,StringBuffer,SrtingBuilder三个对象连接字符串的效率。
比较下究竟谁的效率高。因为我们经常都听有经验的人说,避免使用String通过“+”连接字符串,特
别是连接的次数很多的时候,一定要用StringBuffer,但究竟效率多高,速度多快,我也没有测试过,
所以我就动手测试下,顺便把测试结果跟大家一起分享,希望大家共同讨论此问题。
下边是我的测试代码,可直接运行:

 

public class TestStringConnection {
    
    //连接时间的设定
    private final static int n = 20000;
    
    public static void main(String[] args){
       TestStringConnection test = new TestStringConnection ();
       test.testStringTime(n);
       test.testStringBufferTime(n);
       test.testStringBuilderTime(n);
       
       
//       //连接10次
//       test.testStringTime(10);
//       test.testStringBufferTime(10);
//       test.testStringBuilderTime(10);
//       
//       //连接100
//       
//       test.testStringTime(100);
//       test.testStringBufferTime(100);
//       test.testStringBuilderTime(100);
//       
//       
//       
//       //连接1000
//       
//       test.testStringTime(1000);
//       test.testStringBufferTime(1000);
//       test.testStringBuilderTime(1000);
//       
//       
//      //连接5000
//       
//       test.testStringTime(5000);
//       test.testStringBufferTime(5000);
//       test.testStringBuilderTime(5000);
//       
//       
// //连接10000
//       
//       test.testStringTime(10000);
//       test.testStringBufferTime(10000);
//       test.testStringBuilderTime(10000);
//       
// //连接20000
//       
//       test.testStringTime(20000);
//       test.testStringBufferTime(20000);
//       test.testStringBuilderTime(20000);
    }
    
    /**
     *测试String连接字符串的时间
     */
    public void testStringTime(int n){
       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("//////////////////////连接"+n+"次" );
       System.out.println("String time "+n +":"+ time);
       //System.out.println("String str:" + str);
    }
    
    /**
     *测试StringBuffer连接字符串的时间
     */
    public void testStringBufferTime(int n){
       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 "+n +":"+ time);
       //System.out.println("StringBuffer str:" + str);
    }
    
    /**
     *测试StringBuilder连接字符串的时间
     */
    public void testStringBuilderTime(int n){
       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 " +n +":"+ time);
       
       System.out.println("//////////////////////");
       //System.out.println("StringBuffer str:" + str);
    }

}
 

 

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

 

测试环境:eclipse

由上边的图表结果对比,可以清楚的看出,为什么大家都鼓励用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类的不可变性上,而java程序为了方便简单的
字符串使用方式对+操作符进行了重载,而这个重载的处理可能因此误导很多对java中String的使用。
所以,如果你对字符串中的内容经常进行操作,特别是内容要修改时,那么使用StringBuffer,如果最后
需要String,那么使用StringBuffer的toString()方法好了。但是 StringBuilder 的实例用于多个线程是不安
全的。如果需要这样的同步,则建议使用 StringBuffer,因为StringBuffer是线程安全的。在大多数非多
线程的开发中,为了提高效率,可以采用StringBuilder代替StringBuffer,速度更快。

 

原文地址:http://hi.baidu.com/xinghoney/blog/item/c61ede4c995247ffd62afc2f.html

分享到:
评论

相关推荐

    String、StringBuilder和StringBuffer的区别

    在Java编程语言中,String、StringBuilder和StringBuffer都是用来处理字符串的类,它们之间存在一些重要的区别,主要涉及到性能和线程安全性。 首先,`String`类代表的是字符串常量,一旦创建,其内容就不能改变。...

    字符串连接方面测试时间

    本文将深入探讨在Java中使用不同方法进行字符串连接时的性能差异,特别是针对“+”运算符与`StringBuffer`类在大量字符串连接操作中的表现。 ### 标题解析:“字符串连接方面测试时间” 标题明确了文章的核心主题...

    String StringBuffer和StringBuilder区别之源码解析

    在Java中,字符串是我们经常使用的数据类型,而String、StringBuffer和StringBuilder是Java中三种常用的字符串类。在这篇文章中,我们将从源码角度对String、StringBuffer和StringBuilder进行深入分析,了解它们之间...

    String ,StringBuffer与StringBuilder

    结果显示,使用 StringBuffer 连接字符串的速度非常快,基本上只需要 16 毫秒左右。 由此可见,StringBuffer 的速度几乎是 String 的万倍。当然,这个数据不是很准确,因为循环的次数在 100000 次的时候,差异更大...

    从源码角度简单看StringBuilder和StringBuffer的异同(全面解析)

    StringBuilder和StringBuffer的异同解析 StringBuilder和StringBuffer是Java中两个常用的字符串...了解StringBuilder和StringBuffer的异同可以帮助开发者更好地选择合适的字符串处理类,提高应用程序的效率和安全性。

    String、StringBuffer、StringBuilder的使用方法

    在Java编程语言中,`String`、`StringBuffer`和`StringBuilder`是处理字符串的三个重要类,它们各自有特定的使用场景和优缺点。理解它们的差异对于编写高效的代码至关重要。 **String类** `String`是不可变的类,...

    StringBuilder拼接字符串

    C# StringBuilder 拼接字符串 字符串转换工具 StringBuilder比StringBuffer运行速度要快,因为StringBuilder是针对于单线程的,所这它是非线程安全的。普通情况下建议使用StringBuilder。

    String及StringBuffer和StringBuilder的区别

    String、StringBuffer 和 StringBuilder 是 Java 语言中三种不同类型的字符串处理方式,它们之间存在着明显的性能和线程安全性差异。 String String 类型是不可变的对象,每次对 String 对象进行改变时都会生成一...

    Java字符串连接效率[参照].pdf

    本文主要讨论了Java中的String、StringBuilder和StringBuffer三个类在字符串连接方面的性能差异。 首先,String类在Java中是不可变的,这意味着一旦创建,其值就不能改变。字符串常量存储在常量池中,这有助于节省...

    StringBuilder字符串拼接工具

    这是因为每次使用`+`进行字符串连接时,Java都会创建新的`String`对象,这在内存管理和效率上都是不理想的。而`StringBuilder`则允许我们在一个可变的对象中添加字符,避免了频繁的内存分配。 标题"StringBuilder...

    JAVA 字符串 操作

    - `StringBuilder`和`StringBuffer`类:用于大量字符串拼接,线程安全,性能优于`+`。 5. 查找与替换: - `indexOf()`:查找子字符串首次出现的位置。 - `lastIndexOf()`:查找子字符串最后一次出现的位置。 - ...

    StringBuffer 和 StringBuilder 类

    在Java编程中,当我们需要对字符串进行多次修改时,StringBuffer和StringBuilder类成为首选。这两个类提供了一种高效且灵活的方式来处理字符串,与不可变的String类相比,它们能避免创建大量未使用的对象,从而提高...

    java 创建字符串类

    Java提供了两种主要的方式来创建字符串:通过`String`类的构造方法和使用`StringBuilder`或`StringBuffer`类。以下是对这些知识点的详细解释: 1. **String类**: - **不可变性**:Java中的`String`对象是不可变的...

    连接 字符 串.rar

    - 确保所有字符串都使用相同的编码进行连接,以避免乱码问题。 6. **内存管理和垃圾回收**: - 在动态内存管理的语言(如Java、Python)中,连接字符串后,旧的字符串对象可能会被垃圾回收器自动清理。 - 在C/...

    java基础--4.常用类-3.StringBuffer、StringBuilder

    在Java编程语言中,`StringBuffer`和`StringBuilder`是两个非常重要的类,它们主要用于处理字符串的拼接和修改操作。这两个类位于`java.lang`包下,因此在使用时无需显式导入。本篇文章将深入探讨这两个类的特性和...

    String-StringBuffer-StringBuilder

    在Java编程语言中,`String`、`StringBuffer`和`StringBuilder`都是用来处理字符串的类,但它们之间存在显著的差异,主要体现在性能、线程安全性和使用场景上。 首先,`String`是最基本的字符串类,它代表的是不可...

    JavaScript 利用StringBuffer类提升+=拼接字符串效率

    在JavaScript中进行字符串拼接时,频繁使用+=操作符可能会导致性能问题,因为每次拼接都会创建新的字符串并执行一系列复制和更新操作。为了优化这一过程,我们可以利用StringBuffer类来提升拼接字符串的效率。 首先...

    关于字符串相等的比较

    - 当需要构建或修改字符串时,使用 `StringBuilder`(线程不安全)或 `StringBuffer`(线程安全)比拼接多个字符串更高效。 - 示例:使用 `StringBuilder` 构建最终的字符串后,再使用 `equals` 方法进行比较。 -...

    String和StringBuilder效率测试

    在Java编程语言中,`String`和`StringBuilder`都是用于处理字符串的重要类,但它们在处理方式和效率上有显著的区别。本资源中的代码是针对这两种类的效率进行测试的实例,旨在帮助开发者理解它们在不同场景下的性能...

Global site tag (gtag.js) - Google Analytics