`
vipshichg
  • 浏览: 267482 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

JAVA字符串拼接各种方式的性能比较

    博客分类:
  • java
阅读更多

在JAVA中拼接两个字符串的最简便的方式就是使用操作符”+”了。如果你用”+”来连接固定长度的字符串,可能性能上会稍受影响,但是如果你是在 循环中来”+”多个串的话,性能将指数倍的下降。假设有一个字符串,我们将对这个字符串做大量循环拼接操作,使用”+”的话将得到最低的性能。但是究竟这 个性能有多差?如果我们同时也把StringBuffer,StringBuilder或String.concat()放入性能测试中,结果又会如何 呢?本文将会就这些问题给出一个答案!

我们将使用Per4j来计算性能,因为这个工具可以给我们一个完整的性能指标集合,比如最小,最大耗时,统计时间段的标准偏差等。在测试代码中,为了得到一个准确的标准偏差值,我们将执行20个拼接”*”50,000次的测试。下面是我们将使用到的拼接字符串的方法:

  • Concatenation Operator (+)
  • String concat method – concat(String str)
  • StringBuffer append method – append(String str)
  • StringBuilder append method – append(String str)

最后,我们将看看字节码,来研究这些方法到底是如何执行的。现在,让我们先开始来创建我扪的类。注意为了计算每个循环的性能,代码中的每段测试代码都需要用Per4J库进行封装。首先我们先定义迭代次数 

  1. private static  final int  OUTER_ITERATION=20;  
  2. private static final int INNER_ITERATION=50000;  

接下来,我们将使用上述4个方法来实现我们的测试代码。

  1. String addTestStr = "";  
  2.  
  3. String concatTestStr = "";  
  4.  
  5. StringBuffer concatTestSb = null;  
  6.  
  7. StringBuilder concatTestSbu = null;  
  8.  
  9. for (int outerIndex=0;outerIndex<=OUTER_ITERATION;outerIndex++) {  
  10.  
  11.     StopWatch stopWatch = new LoggingStopWatch("StringAddConcat");  
  12.  
  13.     addTestStr = "";  
  14.  
  15.     for (int innerIndex=0;innerIndex<=INNER_ITERATION;innerIndex++)  
  16.  
  17.     addTestStr += "*";  
  18.  
  19.     stopWatch.stop();  
  20.  
  21. }        
  22.  
  23. for (int outerIndex=0;outerIndex<=OUTER_ITERATION;outerIndex++) {  
  24.  
  25.     StopWatch stopWatch = new LoggingStopWatch("StringConcat");  
  26.  
  27.     concatTestStr = "";  
  28.  
  29.     for (int innerIndex=0;innerIndex<=INNER_ITERATION;innerIndex++)  
  30.  
  31.     concatTestStr.concat("*");  
  32.  
  33.     stopWatch.stop();  
  34.  
  35. }  
  36.  
  37. for (int outerIndex=0;outerIndex<=OUTER_ITERATION;outerIndex++) {  
  38.  
  39.     StopWatch stopWatch = new LoggingStopWatch("StringBufferConcat");  
  40.  
  41.     concatTestSb = new StringBuffer();  
  42.  
  43.     for (int innerIndex=0;innerIndex<=INNER_ITERATION;innerIndex++)  
  44.  
  45.     concatTestSb.append("*");  
  46.  
  47.     stopWatch.stop();  
  48.  
  49. }  
  50.   
  51. for (int outerIndex=0;outerIndex<=OUTER_ITERATION;outerIndex++) {  
  52.  
  53.     StopWatch stopWatch = new LoggingStopWatch("StringBuilderConcat");  
  54.  
  55.     concatTestSbu = new StringBuilder();  
  56.  
  57.     for (int innerIndex=0;innerIndex<=INNER_ITERATION;innerIndex++)  
  58.  
  59.     concatTestSbu.append("*");  
  60.  
  61.     stopWatch.stop();  
  62.  
  63. }  

 

接下来通过运行程序来生成性能指标。我的运行环境是64位的Windown7操作系统,32位的JVM(7-ea) 带4GB内存,双核Quad 2.00GHz的CPU的机器.

经过20次迭代后,我们得到如下的数据:


 

结果非常完美如我们想象的那样。唯一比较有趣的事情是为什么String.concat也很不错,我们都知道,String是一个常类(初始化后就不会改变的类),那么为什么concat的性能会更好一些呢。(译者注: 其实原文作者的测试代码有问题,对于concat()方法的测试代码应该写成 concatTestStr=concatTestStr.concat(“*”)才对。)为了回答这个问题,我们应该看看concat反编译出来的字节 码。在本文的下载包里面包含了所有的字节码,但是现在我们先看一下concat的这个代码片段:

  1. 46:  new #6//class java/lang/StringBuilder 
  2. 49:  dup 
  3. 50:  invokespecial   #7//Method java/lang/StringBuilder."<init>":()V 
  4. 53:  aload_1 
  5. 54:  invokevirtual   #8//Method java/lang/StringBuilder.append: 
  6.          (Ljava/lang/String;)Ljava/lang/StringBuilder; 
  7. 57:  ldc #9//String * 
  8. 59:  invokevirtual   #8//Method java/lang/StringBuilder.append: 
  9.          (Ljava/lang/String;)Ljava/lang/StringBuilder; 
  10. 62:  invokevirtual   #10//Method java/lang/StringBuilder.toString:() 
  11.          Ljava/lang/String; 
  12. 65:  astore_1 
  13. 66:  iinc    71 
  14. 69:  goto    38 

这段代码是String.concat()的字节码,从这段代码中,我们可以清楚的看到,concat()方法使用了 StringBuilder,concat()的性能应该和StringBuilder的一样好,但是由于额外的创建StringBuilder和 做.append(str).append(str).toString()的操作,使得concate的性能会受到一些影响,所以 StringBuilder和String Cancate的时间是1.8和3.3。

因此,即时在做最简单的拼接时,如果我们不想创建StringBuffer或StringBuilder实例使,我们也因该使用concat。但是对于大量的字符串拼接操作,我们就不应该使用concat(译者注:因 为测试代码功能上并不完全等价,更换后的测试代码concat的平均处理时间是1650.9毫秒。这个结果在原文的评论里面。),因为concat会降低 你程序的性能,消耗你的cpu。因此,在不考虑线程安全和同步的情况下,为了获得最高的性能,我们应尽量使用StringBuilder

本文的源代码,编译目标文件和字节码可以通过下面的这个链接获得:

下载源代码,类和字节码:String_Concatenation _Performance.zip

原文链接:http://www.venishjoe.net/2009/11/java-string-concatenation-and.html

  • 大小: 29.6 KB
2
8
分享到:
评论
3 楼 devilyard 2013-08-20  
转载来的文章吧,是哪个版本的JDK呢
2 楼 kjmmlzq19851226 2013-08-20  
还没说完 我想了解一下,如果在builder外加个synchronized,是否buffer和builder效率相近,如果楼主感兴趣可以帮帮测试一把
1 楼 kjmmlzq19851226 2013-08-20  
buffer性能的确略低于builder,因为buffer是thread-safe的。

相关推荐

    JAVA的字符串拼接与性能

    JAVA的字符串拼接与性能 概述:本文主要研究的是JAVA的字符串拼接的性能,原文中的测试代码在功能上并不等价,导致concat的测试意义不大。不过原作者在评论栏给了新的concat结果,如果有兴趣的同学建议自己修改代码...

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

    本文主要探讨了在Java中几种不同的字符串拼接方法的性能差异,包括使用操作符`+`、`String.concat()`、`StringBuffer.append()`和`StringBuilder.append()`。以下是对这些方法的详细分析: 1. **字符串拼接操作符 ...

    Java字符串拼接效率测试过程解析

    Java字符串拼接的方式有多种,包括使用String、StringBuffer和StringBuilder等。每种方式都有其优缺,选择哪种方式取决于具体的应用场景。 使用String进行字符串拼接是最简单的一种方式,但是在大量字符串拼接时,...

    SQL2JAVA-java字段串代码拼接小工具

    在Java中,有多种方式可以实现字符串拼接,比如使用`+`操作符,但当拼接的字符串数量较多时,这种方式的效率较低。因此,更推荐使用`StringBuffer`或`StringBuilder`类,它们提供了一种可扩展且高效的字符串操作方法...

    将excal批量数据插入到postgresql数据库(目前实现字符串拼接的方式)

    在本教程中,我们将聚焦于如何将Excel数据批量导入到PostgreSQL数据库,特别关注一种常见的方法——通过字符串拼接的方式。PostgreSQL是一个功能强大的开源关系型数据库管理系统,而Excel则是广泛使用的电子表格工具...

    JAVA 字符串 操作

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

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

    总之,理解和掌握Java字符串拼接的性能差异是优化代码的关键。正确选择拼接方法可以帮助我们编写出运行更快、资源消耗更低的程序。在实际开发中,应根据具体情况选择最适合的字符串处理策略,以提高程序的效率和响应...

    +作为java中的拼接字符串的功能

    该程序通过比较使用"+"和`StringBuffer`进行字符串拼接所需的时间,可以看出后者在性能上明显优于前者。 #### 总结 综上所述,虽然"+"运算符用于字符串拼接非常方便,但在涉及大量拼接操作时应考虑使用`...

    Java 字符串的拼接详解

    下面我们将深入探讨Java字符串拼接的原理、性能影响以及编译器的优化策略。 首先,当我们用`+`运算符或`StringBuilder`/`StringBuffer`进行字符串拼接时,由于String的不可变性,每次拼接都会创建新的字符串对象。...

    StringBuilder字符串拼接工具

    总的来说,`StringBuilder`是Java中处理字符串拼接的关键工具,尤其在需要高效构建长字符串的场景下。它提供了灵活的方法来添加内容,且避免了不必要的内存开销。通过使用`StringBuilder`,开发者可以编写出更高效、...

    Java 字符串连接的性能问题分析

    如果拼接的字符串很多,使用字符串连接符的计算时间和对性能的消耗变得难以估算。 问题原因 主要原因是 String 类的不可变性。当连接两个字符串时,需要创建一个新的字符串对象,导致大量的对象创建和销毁,从而...

    java实验-字符串.docx

    而StringBuffer类是可变的,可以使用`append()`方法添加内容,而不必每次都创建新对象,因此在处理大量字符串拼接时,StringBuffer的效率更高。 总结来说,这个实验旨在帮助我们理解和掌握Java中字符串的基本操作,...

    ibatis拼接字符串

    在本篇文章中,我们将深入探讨如何使用 Java 编程语言结合 iBatis 框架进行 SQL 字符串的动态拼接。通过分析提供的代码片段,我们可以了解到在实际开发过程中,这种动态 SQL 的构建方式非常常见,尤其是在处理复杂的...

    java字符串实验题目

    这时,StringBuilder和StringBuffer类就派上用场了,它们提供了可变的字符串操作,适合在循环中进行字符串拼接,性能优于使用"+"运算符。 Java异常处理也是编程中的重要组成部分。在处理字符串相关的问题时,可能会...

    java中的字符串处理

    这种设计使得Java能够提供丰富的字符串处理功能,包括但不限于比较、搜索、连接以及大小写转换等。 #### 二、String类型的特点 1. **不可变性**:创建了一个`String`对象后,该对象所表示的字符串是不可改变的。这...

    Java 字符串与文本相关实例源码

    - 使用`StringBuilder`或`StringBuffer`进行字符串拼接和修改,这两个类是线程安全的。 - `append()`: 追加字符串。 - `insert()`: 在指定位置插入字符串。 - `replace()`: 替换部分字符串。 7. **字符串编码与...

    for循环中如何正确使用字符串拼接

    在Java编程中,字符串拼接是一项常见的操作,尤其是在循环中,高效的字符串拼接方式对于程序性能至关重要。在本文中,我们将探讨在`for`循环中如何正确使用字符串拼接,并分析几种常见方法的效率和底层实现。 首先...

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

    今天,我们将通过测试和分析,比较 Java 中 5 种不同的字符串拼接方法的效率,并探究每种方法背后的实现原理。 第一种方法:使用 + 运算符 在 Java 中,我们可以使用 + 运算符来拼接字符串。这是最简单的方法,但其...

Global site tag (gtag.js) - Google Analytics