假设有一个字符串,我们将对这个字符串做大量循环拼接操作,使用”+”的话将得到最低的性能。但是究竟这个性能有多差?如果我们同时也把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的机器

结果非常完美如我们想象的那样。唯一比较有趣的事情是为什么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."":()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。

java 字符串倍_java字符串拼接与性能分析详解相关推荐

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

    假设有一个字符串,我们将对这个字符串做大量循环拼接操作,使用"+"的话将得到最低的性能.但是究竟这个性能有多差?如果我们同时也把StringBuffer,StringBuilder ...

  2. Java指令全集_Java的JVM字节码指令集详解

    本文详细介绍了如何使用javap查看java方法中的字节码.以及各种字节码的含义,并且配以完善的案例,一步步,从头到尾带领大家翻译javap的输出.在文末还附有JVM字节码指令集表. 本文不适合没有J ...

  3. java mod %区别_Java中 % 与Math.floorMod() 区别详解

    %为取余(rem),Math.floorMod()为取模(mod) 取余取模有什么区别呢? 对于整型数a,b来说,取模运算或者取余运算的方法都是: 1.求 整数商: c = a/b; 2.计算模或者余 ...

  4. java 静态 编译_Java中的动态和静态编译实例详解

    Java中的动态和静态编译实例详解 首先,我们来说说动态和静态编译的问题. Q: java和javascript有什么区别? 总结了一下:有以下几点吧: 1.首先从运行环境来说java代码是在JVM上 ...

  5. java switch 值_Java switch多值匹配操作详解

    这篇文章主要介绍了Java switch多值匹配操作详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 我们都知道 switch 用来走流程分支,大 ...

  6. java file用法_Java File 类的使用方法详解(转)

    转自:http://www.codeceo.com/article/java-file-class.html Java File类的功能非常强大,利用Java基本上可以对文件进行所有的操作.本文将对J ...

  7. java 分割数据_java 分割csv数据的实例详解

    java 分割csv数据的实例详解 实际需要解析的csv中很多都是从excel中转过来的,数据中本身包含了逗号的数据导致split的过程中发现数据对不上,因此,基于这种特性,重新写了一个csv数据的分 ...

  8. java 接口函数_Java函数式接口Supplier接口实例详解

    这篇文章主要介绍了Java函数式接口Supplier接口实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 JDK提供了大量常用的函数式接口以丰 ...

  9. java foreach标签_Java中Velocity foreach循环标签详解

    Java中Velocity foreach循环标签详解 Java Velocity中foreach循环可以很容易的遍历数组或者集合. 定义 #foreach( $elem in $allElems) ...

最新文章

  1. 8.局部变量/全局变量global/内嵌函数/闭包nonlocal
  2. webpack打包的两种方式
  3. 【西交ACM】298 第N大的数
  4. S2SH框架入门之使用hibernate进行基础的增删改查
  5. vue.js根据数据循环生成表格_vue.js循环for(列表渲染)详解
  6. JS中配置打开邮箱的链接
  7. Python 标准库 —— queue、heapq与PriorityQueue
  8. MySQL Server 安装失败
  9. 粒子群优化算法及其应用
  10. IOS 隐藏app图标
  11. 关于勾股数的规律及证明
  12. Java:Hutool工具箱之Hutool-crypto加密解密
  13. Impala: Reducing query concurrency or configuring admission control may help avoid this error
  14. [Zer0pts2020]easy strcmp细节探究
  15. css一些零零散散的问题
  16. Synergy v1.10版本跨平台鼠键共享资源
  17. Python+Vue计算机毕业设计大数据在线考试系统在线阅卷系统及大数据统计分析7o33p(源码+程序+LW+部署)
  18. Athroes 9344 刷写 uboot
  19. 操作系统面试题(十二):逻辑地址和物理地址
  20. CSS+JS 实现最简单的流星雨

热门文章

  1. 计算机网络四个阶段的发展特点,计算机网络的发展分哪四个阶段,特点?
  2. 牛客网---Java题库(21~30)
  3. MySQL中concat以及group_concat的使用
  4. Mybatis框架_part1
  5. 解决outlook无法启动
  6. 分析一个文本文件(英文文章)中各个词出现的频率,并且把频率最高的十个词打印出来...
  7. HDU-4618 Palindrome Sub-Array 暴力枚举
  8. 简单的多线程实例下载(供初学者下载学习)
  9. 一个基于WF的业务流程平台
  10. [文章备份]RSS阅读器在手机上APP配置方法