在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库进行封装。首先我们先定义迭代次数
- private static final int OUTER_ITERATION=20;
- private static final int INNER_ITERATION=50000;
接下来,我们将使用上述4个方法来实现我们的测试代码。
- String addTestStr = "";
- String concatTestStr = "";
- StringBuffer concatTestSb = null;
- StringBuilder concatTestSbu = null;
- for (int outerIndex=0;outerIndex<=OUTER_ITERATION;outerIndex++) {
- StopWatch stopWatch = new LoggingStopWatch("StringAddConcat");
- addTestStr = "";
- for (int innerIndex=0;innerIndex<=INNER_ITERATION;innerIndex++)
- addTestStr += "*";
- stopWatch.stop();
- }
- for (int outerIndex=0;outerIndex<=OUTER_ITERATION;outerIndex++) {
- StopWatch stopWatch = new LoggingStopWatch("StringConcat");
- concatTestStr = "";
- for (int innerIndex=0;innerIndex<=INNER_ITERATION;innerIndex++)
- concatTestStr.concat("*");
- stopWatch.stop();
- }
- for (int outerIndex=0;outerIndex<=OUTER_ITERATION;outerIndex++) {
- StopWatch stopWatch = new LoggingStopWatch("StringBufferConcat");
- concatTestSb = new StringBuffer();
- for (int innerIndex=0;innerIndex<=INNER_ITERATION;innerIndex++)
- concatTestSb.append("*");
- stopWatch.stop();
- }
- for (int outerIndex=0;outerIndex<=OUTER_ITERATION;outerIndex++) {
- StopWatch stopWatch = new LoggingStopWatch("StringBuilderConcat");
- concatTestSbu = new StringBuilder();
- for (int innerIndex=0;innerIndex<=INNER_ITERATION;innerIndex++)
- concatTestSbu.append("*");
- stopWatch.stop();
- }
接下来通过运行程序来生成性能指标。我的运行环境是64位的Windown7操作系统,32位的JVM(7-ea) 带4GB内存,双核Quad 2.00GHz的CPU的机器.
经过20次迭代后,我们得到如下的数据:
结果非常完美如我们想象的那样。唯一比较有趣的事情是为什么String.concat也很不错,我们都知道,String是一个常类(初始化后就不会改变的类),那么为什么concat的性能会更好一些呢。(译者注: 其实原文作者的测试代码有问题,对于concat()方法的测试代码应该写成 concatTestStr=concatTestStr.concat(“*”)才对。)为了回答这个问题,我们应该看看concat反编译出来的字节 码。在本文的下载包里面包含了所有的字节码,但是现在我们先看一下concat的这个代码片段:
- 46: new #6; //class java/lang/StringBuilder
- 49: dup
- 50: invokespecial #7; //Method java/lang/StringBuilder."<init>":()V
- 53: aload_1
- 54: invokevirtual #8; //Method java/lang/StringBuilder.append:
- (Ljava/lang/String;)Ljava/lang/StringBuilder;
- 57: ldc #9; //String *
- 59: invokevirtual #8; //Method java/lang/StringBuilder.append:
- (Ljava/lang/String;)Ljava/lang/StringBuilder;
- 62: invokevirtual #10; //Method java/lang/StringBuilder.toString:()
- Ljava/lang/String;
- 65: astore_1
- 66: iinc 7, 1
- 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
相关推荐
JAVA的字符串拼接与性能 概述:本文主要研究的是JAVA的字符串拼接的性能,原文中的测试代码在功能上并不等价,导致concat的测试意义不大。不过原作者在评论栏给了新的concat结果,如果有兴趣的同学建议自己修改代码...
本文主要探讨了在Java中几种不同的字符串拼接方法的性能差异,包括使用操作符`+`、`String.concat()`、`StringBuffer.append()`和`StringBuilder.append()`。以下是对这些方法的详细分析: 1. **字符串拼接操作符 ...
Java字符串拼接的方式有多种,包括使用String、StringBuffer和StringBuilder等。每种方式都有其优缺,选择哪种方式取决于具体的应用场景。 使用String进行字符串拼接是最简单的一种方式,但是在大量字符串拼接时,...
在Java中,有多种方式可以实现字符串拼接,比如使用`+`操作符,但当拼接的字符串数量较多时,这种方式的效率较低。因此,更推荐使用`StringBuffer`或`StringBuilder`类,它们提供了一种可扩展且高效的字符串操作方法...
在本教程中,我们将聚焦于如何将Excel数据批量导入到PostgreSQL数据库,特别关注一种常见的方法——通过字符串拼接的方式。PostgreSQL是一个功能强大的开源关系型数据库管理系统,而Excel则是广泛使用的电子表格工具...
- `StringBuilder`和`StringBuffer`类:用于大量字符串拼接,线程安全,性能优于`+`。 5. 查找与替换: - `indexOf()`:查找子字符串首次出现的位置。 - `lastIndexOf()`:查找子字符串最后一次出现的位置。 - ...
总之,理解和掌握Java字符串拼接的性能差异是优化代码的关键。正确选择拼接方法可以帮助我们编写出运行更快、资源消耗更低的程序。在实际开发中,应根据具体情况选择最适合的字符串处理策略,以提高程序的效率和响应...
该程序通过比较使用"+"和`StringBuffer`进行字符串拼接所需的时间,可以看出后者在性能上明显优于前者。 #### 总结 综上所述,虽然"+"运算符用于字符串拼接非常方便,但在涉及大量拼接操作时应考虑使用`...
下面我们将深入探讨Java字符串拼接的原理、性能影响以及编译器的优化策略。 首先,当我们用`+`运算符或`StringBuilder`/`StringBuffer`进行字符串拼接时,由于String的不可变性,每次拼接都会创建新的字符串对象。...
总的来说,`StringBuilder`是Java中处理字符串拼接的关键工具,尤其在需要高效构建长字符串的场景下。它提供了灵活的方法来添加内容,且避免了不必要的内存开销。通过使用`StringBuilder`,开发者可以编写出更高效、...
如果拼接的字符串很多,使用字符串连接符的计算时间和对性能的消耗变得难以估算。 问题原因 主要原因是 String 类的不可变性。当连接两个字符串时,需要创建一个新的字符串对象,导致大量的对象创建和销毁,从而...
而StringBuffer类是可变的,可以使用`append()`方法添加内容,而不必每次都创建新对象,因此在处理大量字符串拼接时,StringBuffer的效率更高。 总结来说,这个实验旨在帮助我们理解和掌握Java中字符串的基本操作,...
在本篇文章中,我们将深入探讨如何使用 Java 编程语言结合 iBatis 框架进行 SQL 字符串的动态拼接。通过分析提供的代码片段,我们可以了解到在实际开发过程中,这种动态 SQL 的构建方式非常常见,尤其是在处理复杂的...
这时,StringBuilder和StringBuffer类就派上用场了,它们提供了可变的字符串操作,适合在循环中进行字符串拼接,性能优于使用"+"运算符。 Java异常处理也是编程中的重要组成部分。在处理字符串相关的问题时,可能会...
这种设计使得Java能够提供丰富的字符串处理功能,包括但不限于比较、搜索、连接以及大小写转换等。 #### 二、String类型的特点 1. **不可变性**:创建了一个`String`对象后,该对象所表示的字符串是不可改变的。这...
- 使用`StringBuilder`或`StringBuffer`进行字符串拼接和修改,这两个类是线程安全的。 - `append()`: 追加字符串。 - `insert()`: 在指定位置插入字符串。 - `replace()`: 替换部分字符串。 7. **字符串编码与...
在Java编程中,字符串拼接是一项常见的操作,尤其是在循环中,高效的字符串拼接方式对于程序性能至关重要。在本文中,我们将探讨在`for`循环中如何正确使用字符串拼接,并分析几种常见方法的效率和底层实现。 首先...
今天,我们将通过测试和分析,比较 Java 中 5 种不同的字符串拼接方法的效率,并探究每种方法背后的实现原理。 第一种方法:使用 + 运算符 在 Java 中,我们可以使用 + 运算符来拼接字符串。这是最简单的方法,但其...