`

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个方法来实现我们的测试代码。
  01 String addTestStr = "";
  02 String concatTestStr = "";
  03 StringBuffer concatTestSb = null;
  04 StringBuilder concatTestSbu = null;
  05 for (int outerIndex=0;outerIndex<=OUTER_ITERATION;outerIndex++) {
  06     StopWatch stopWatch = new LoggingStopWatch("StringAddConcat");
  07     addTestStr = "";
  08     for (int innerIndex=0;innerIndex<=INNER_ITERATION;innerIndex++)
  09     addTestStr += "*";
  10     stopWatch.stop();
  11 }
  12 for (int outerIndex=0;outerIndex<=OUTER_ITERATION;outerIndex++) {
  13     StopWatch stopWatch = new LoggingStopWatch("StringConcat");
  14     concatTestStr = "";
  15     for (int innerIndex=0;innerIndex<=INNER_ITERATION;innerIndex++)
  16     concatTestStr.concat("*");
  17     stopWatch.stop();
  18 }
  19 for (int outerIndex=0;outerIndex<=OUTER_ITERATION;outerIndex++) {
  20     StopWatch stopWatch = new LoggingStopWatch("StringBufferConcat");
  21     concatTestSb = new StringBuffer();
  22     for (int innerIndex=0;innerIndex<=INNER_ITERATION;innerIndex++)
  23     concatTestSb.append("*");
  24     stopWatch.stop();
  25 }
  26 for (int outerIndex=0;outerIndex<=OUTER_ITERATION;outerIndex++) {
  27     StopWatch stopWatch = new LoggingStopWatch("StringBuilderConcat");
  28     concatTestSbu = new StringBuilder();
  29     for (int innerIndex=0;innerIndex<=INNER_ITERATION;innerIndex++)
  30     concatTestSbu.append("*");
  31     stopWatch.stop();
  32 }
  接下来通过运行程序来生成性能指标。我的运行环境是64位的Windown7操作系统,32位的JVM(7-ea) 带4GB内存,双核Quad 2.00GHz的CPU的机器.
  经过20次迭代后,我们得到如下的数据:
   


  结果非常完美如我们想象的那样。唯一比较有趣的事情是为什么String.concat也很不错,我们都知道,String是一个常类(初始化后就不会改变的类),那么为什么concat的性能会更好一些呢。(译者注:其实原文作者的测试代码有问题,对于concat()方法的测试代码应该写成concatTestStr=concatTestStr.concat(“*”)才对。)为了回答这个问题,我们应该看看concat反编译出来的字节码。在本文的下载包里面包含了所有的字节码,但是现在我们先看一下concat的这个代码片段:
  01 46:  new #6; //class java/lang/StringBuilder
  02 49:  dup
  03 50:  invokespecial   #7; //Method java/lang/StringBuilder."<init>":()V
  04 53:  aload_1
  05 54:  invokevirtual   #8; //Method java/lang/StringBuilder.append:
  06          (Ljava/lang/String;)Ljava/lang/StringBuilder;
  07 57:  ldc #9; //String *
  08 59:  invokevirtual   #8; //Method java/lang/StringBuilder.append:
  09          (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    7, 1
  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
  • 大小: 50.6 KB
分享到:
评论

相关推荐

    JAVA的字符串拼接与性能

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

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

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

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

    - **`StringBuffer`**:这是Java早期提供的一个线程安全的类,适用于多线程环境下的字符串拼接操作。 - **`StringBuilder`**:自JDK 1.5起被引入,它与`StringBuffer`非常相似,但不保证线程安全,因此在单线程环境...

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

    然而,不同的字符串拼接方式在性能上存在显著差异。本篇文章将深入探讨Java中的字符串拼接技术,以及它们对程序效率的影响。 首先,最直观的字符串拼接方式是使用操作符“+”。这种做法简单易懂,但在循环中频繁...

    JAVA 字符串 操作

    本文将深入探讨Java中的字符串操作,包括创建、比较、拼接、查找与替换、分割以及格式化。 1. 创建字符串: Java中有两种方式创建字符串:通过`new`关键字或使用字符串字面量。 - 使用`new`关键字:`String str =...

    ibatis拼接字符串

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

    Java中字符串.pdf

    在Java编程语言中,字符串是一个至关重要的概念,它是由一个或多个字符组成的序列。字符串在内存中被视为不可变对象,...在实际编程中,根据需求选择合适的字符串类型,并充分利用提供的API,可以优化性能和代码质量。

    java中的字符串处理

    - 提升了性能,因为JVM可以缓存这些不变的字符串,避免重复创建相同的字符串对象。 - 有助于提高代码的简洁性和可读性。 2. **内部实现**:由于字符串不可变,因此Java使用了高效的内部存储结构(如字符数组)来...

    java实验-字符串.docx

    这种操作在频繁的字符串拼接中会降低效率,因为每次都会创建新的对象。而StringBuffer类是可变的,可以使用`append()`方法添加内容,而不必每次都创建新对象,因此在处理大量字符串拼接时,StringBuffer的效率更高。...

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

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

    java字符串实验题目

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

    java 创建字符串缓存类

    这是因为Java中的字符串是不可变的,每次对字符串进行修改都会生成一个新的对象,这可能会导致内存消耗增加和性能下降。为了解决这个问题,我们可以自定义一个字符串缓冲类来存储和复用字符串,以提高效率。 首先,...

    java 插入新的字符串

    本文将深入探讨如何在Java中插入新的字符串,主要围绕`StringBuffer`类进行讲解,因为它是线程安全且高效地处理字符串拼接的首选工具。此外,我们还将讨论与其相关的`StringBuilder`类,尽管它不适用于多线程环境,...

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

    本实例源码集主要关注Java中的字符串和文本处理,提供了多种实际应用的示例,帮助开发者深入理解和运用相关功能。 1. **字符串创建与初始化** - `String`类的构造方法:`new String()`,`String(string)`,`String...

    JAVA 数组与字符串课程文档

    在处理字符串时,可以使用`StringBuffer`或`StringBuilder`类进行高效的字符串拼接操作,尤其在循环中,这两个类比直接使用`+`操作符更有效率。 数组和字符串在实际编程中常常结合使用,比如在一个字符串数组中存储...

    java 去掉重复字符 三个方法

    这个方法利用了Java 8的特性,将字符串转换为整数流(每个字符的ASCII值),然后使用`distinct()`过滤重复,再通过`mapToObj()`将每个整数转换回字符,并最终使用`toArray()`生成新的字符串。 总结来说,去除Java...

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

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

    mybatis Mapper.xml中传参多选 字符串形式逗号分隔 AND中拼接OR.rar

    例如,如果用户选择的标签以逗号分隔的字符串"tag1,tag2,tag3"传入,我们可以在Java代码中将其分割并存入List。 接下来,我们将焦点转到Mapper.xml文件。在SQL语句中,我们可以使用`&lt;foreach&gt;`标签来遍历集合中的...

Global site tag (gtag.js) - Google Analytics