Java StringBuilder神话被揭穿

神话

用加号运算符连接两个字符串是万恶之源

-匿名Java开发人员

注意 :此处讨论的测试的源代码可以在Github上找到

从大学时代起,我就学会了使用+运算符将Java中的String连接视为致命的性能缺陷。 最近,在Backbase R&D上进行了一次内部审查,其中每当您使用plus运算符连接String时,由于在javac使用StringBuilder javac ,这种重复的口头禅就被当作神话了。 我准备证明这一点并验证不同环境下的现实。

考试

依靠编译器优化String串联意味着根据您采用的JDK供应商,情况可能会发生重大变化。 就我日常工作所需的平台支持而言,应考虑三个主要供应商:

  • Oracle JDK
  • IBM JDK
  • ECJ-仅适用于开发人员

此外,尽管我们正式支持Java 5至6,但我们也正在考虑为我们的产品提供Java 7支持,在这三个供应商的基础上增加了另外三层的间接。 为了 懒惰 为简单起见, ecj编译的字节码将使用单个JDK(即Oracle JDK7)运行。 我准备了安装了上述所有JDK的Virtualbox VM,然后开发了一些类来表示三种不同的串联方法,根据特定的测试用例,每种方法调用总计三至四个串联。 每个测试回合都运行测试类数千次,每个测试用例总共进行100回合。 相同的VM用于运行同一测试用例的所有回合,并跨不同的测试用例重新启动,所有这些都使Java运行时能够执行所有可能的优化,而不会以任何方式影响其他测试用例。 缺省选项用于启动所有JVM。 可以在基准运行程序脚本中找到更多详细信息。

编码

Github上提供了测试用例和测试套件的完整代码。 产生了以下不同的测试用例,以测量String串联的性能差异,加上直接使用StringBuilder

// String concat with plus
String result = 'const1' + base;
result = result + 'const2';
// String concat with a StringBuilder
new StringBuilder().append('const1').append(base).append('const2').append(append).toString();
}
//String concat with an initialized StringBuilder
new StringBuilder('const1').append(base).append('const2').append(append).toString();

一般的想法是在变量的常量String的开头和结尾都提供一个串联。 后两种情况(两者都显式使用StringBuilder之间的区别在于后者使用1-arg构造函数,该构造函数使用结果的初始部分初始化构建器。

结果

足够多的讨论,您可以在下面查看生成的图形,其中每个数据点对应一个测试回合(例如,同一测试类的1000次执行)。 随后将讨论结果以及更多细节。

卡特彼勒

猫猫

catsb2

讨论

甲骨文JKD5显然是输家,与其他甲骨文相比似乎处于B联赛。 但这实际上不是本练习的范围,因此我们暂时将其忽略。 也就是说,我在上图中观察到了另外两个有趣的地方。 首先是,使用加号运算符与使用显式StringBuilder通常确实存在很大的差异, 尤其是如果您使用的Oracle Java5的执行树时间比其他工作人员差的话。

第二个观察结果是,虽然对于大多数JDK来说,显式StringBuilder通常提供的速度是常规plus运算符的两倍,但IBM JDK6似乎不会遭受任何性能损失,它总是平均需要25ms才能完成任务。所有测试用例。 仔细查看生成的字节码会发现一些有趣的细节

字节码

注意:反编译类也可以在Github上使用。在所有可能的JDK中,即使存在加号, StringBuilders 始终用于实现String串联。 而且,在所有厂商和版本中,同一测试用例几乎没有任何区别 。 唯一的区别是ecj ,这是唯一巧妙地优化CatPlus测试用例以调用StringBuilder的1-arg构造函数而不是0-arg版本的方法。

比较生成的字节码可以揭示在不同场景下可能影响性能的因素:

  • 与plus串联时,只要发生串联,就会创建StringBuilder新实例 。 由于构造函数的无用调用,这很容易导致性能下降,并且由于丢弃实例而给垃圾收集器带来更多压力
  • 如果且仅当您在原始代码中以这种方式编写StringBuilder ,编译器才会照搬您,并且仅使用String的1-arg构造函数来初始化StringBuilder 。 这分别导致对CatSB和CatSB2的StringBuilder.append四个和三个调用。

结论

字节码分析为原始问题提供了最终答案。 您是否需要显式使用StringBuilder来提高性能? 上面的图清楚地表明,除非使用IBM JDK6运行时,否则在使用plus运算符时,您将损失50%的性能,尽管在显式StringBuilder时,它在候选对象上的表现会稍差一些。 同样,看到JIT优化如何影响整体性能也很有趣:例如,即使在两个显式StringBuilder测试用例之间存在不同的字节码,从长远来看,最终结果也绝对相同。

神话证实
参考: Java StringBuilder神话从我们的JCG合作伙伴 Carlo Sciolla在Skuro博客中揭穿 。

翻译自: https://www.javacodegeeks.com/2013/03/java-stringbuilder-myth-debunked.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/368947.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

UOJ #149. 【NOIP2015】子串

有两个仅包含小写英文字母的字符串 A 和 B。 现在要从字符串 A 中取出 k 个互不重叠的非空子串,然后把这 k 个子串按照其在字符串 A 中出现的顺序依次连接起来得到一个新的字符串。请问有多少种方案可以使得这个新串与字符串 B 相等? 注意:子…

一张正方形图片,伴随我一年半,敢问情绪的使用方法

【问题的由来】 图片适配正方形显示方法一 <style> .box{width:400px;height:400px;border:solid 5px red;margin:0 auto;background:#f4f4f4 url() no-repeat center;background-size:cover;} </style> <div class"box" style"background-imag…

java3d创建立方体_Opengl创建几何实体——四棱锥和立方体

//#include #include #include using namespace std;float rtri;float rquad;GLfloat points0[5][3] { {0,1,0},{-1,-1,1},{1,-1,1},{1,-1,-1},{-1,-1,-1} };GLfloat points1[8][3] { {1,1,-1},{-1,1,-1},{-1,1,1},{1,1,1},{1,-1,1},{-1,-1,1},{-1,-1,-1},{1,-1,-1} };//四棱…

《软件需求十步走》阅读笔记06

开发因需求而来&#xff0c;需求开发以需求规划的成果为主要依据。软件需求开发首先要做的是获取需求&#xff0c;得到目标&#xff0c;系统关联情况以及用例的分析&#xff1b;其次是需求分析&#xff0c;软件系统的可行性&#xff0c;用户接口&#xff0c;系统功能&#xff0…

WSO2 ESB的一种消息传递方式

正如我之前在WSO2 ESB工作时所发布的那样。 为了更好地理解此ESB&#xff0c;我一直在浏览示例 &#xff08;尚未完成所有示例 &#xff09;。 示例12是关于与ESB的单向消息传递&#xff0c;并使用TCP监视器使其可见。 我之前已经介绍过如何设置类似的工具“ TcpTunnelGUI”&am…

Eclipse-Java代码规范和质量检查插件-Checkstyle

CheckStyle是SourceForge下的一个项目&#xff0c;提供了一个帮助JAVA开发人员遵守某些编码规范的工具。它能够自动化代码规范检查过程&#xff0c;从而使得开发人员从这项重要但枯燥的任务中解脱出来。它可以根据设置好的编码规则来检查代码。比如符合规范的变量命名&#xff…

HTML CSS基础

第一章 一、样式 1、行间样式&#xff0c;代码不可维护&#xff0c;不推荐 2、内联样式&#xff0c;不可重用&#xff0c;不推荐 3、外联样式&#xff0c;可重用&#xff0c;可维护&#xff0c;推荐 <link rel"stylesheet" href"...css" /> 二、…

2018-04-22接口自动化测试学习心得(1)

根据接口文档写接口测试用例-->添加接口自动化测试项目相关依赖(httpclienttestngpoi-ooxmllog4jmailmysql-connector-java)-->写接口测试方法-->执行测试 -- 接口测试1.一个接口就是一个函数2.我们要保证一个接口能够在url地址栏里面访问到&#xff0c;必须满足一下两…

Java MemoryMapped文件的功能

Java MemoryMapped文件的功能 在JDK 1.4中&#xff0c;将内存映射文件的有趣功能添加到Java中&#xff0c;该功能允许将任何文件映射到OS内存以进行有效读取。 内存映射文件可用于开发IPC类型的解决方案。 本文是使用内存映射文件创建IPC的实验。 有关内存映射文件的一些详细信…

介绍一款好用 mongodb 可视化工具

最近想自己搭建一个个人博客&#xff0c;所以学了下mongodb&#xff0c;mongodb是用命令行输入的&#xff0c;有些人可能不太习惯&#xff0c;我自己找了下mongodb的一些可视化工具&#xff0c;发现了一款adminmongo很好用&#xff0c;这里介绍给你们用一下。 github地址&#…

用CSS3来代替JS实现交互

【CSS3和JS】 对于CSS了解的同学都知道&#xff0c;CSS的实现是最底层的&#xff0c;在实现方式和性能上都不是&#xff0c;JS这种提供接口的脚本可比的&#xff1b;从CSS3的动画和JS动画对比角度来看两者&#xff0c;会更清晰&#xff1b;而且随着前端框架的使用&#xff0c;…

php 如何宏定义,php – 在html中实现宏定义的方法

也许显而易见,但C预处理器可以完成这项工作.index._html#define _em(a) a #define _image(a, b) #define _list(a, b, c) a \\ b \ c \#define _theTile The Bar Title#include "head._html"_list(foo, bar, bean)This is really _em(great)_image(media/cat.jpg, …

python——函数 11、命名空间

三种名称空间1、内置名称空间&#xff1a; python解释器自带的名字,如&#xff1a;print、sum、max 当解释器启动时就会形成这个空间 2、全局名称空间&#xff1a; 执行python程序时就会产生这个空间 在每行顶端写代码 a10 def foo():print(a) foo() View Code3&…

Hadoop如何工作? HDFS案例研究

Apache Hadoop软件库是一个框架&#xff0c;该框架允许使用简单的编程模型跨计算机集群对大型数据集进行分布式处理。 它旨在从单个服务器扩展到数千台机器&#xff0c;每台机器都提供本地计算和存储。 库本身不用于依靠硬件来提供高可用性&#xff0c;而是被设计用来检测和处…

CS Round#53 E Maxor

题意&#xff1a;给你N个数&#xff0c;你可以从中选出两个数将它们or起来得到M&#xff0c;求M的最大值及得到最大值的方案数。 刚了半个小时得到了一个貌似时O(N log max(Ai)^2)的方法&#xff0c;想了想发现貌似只能做出第一问&#xff0c;但好像改一下就能搞掉第二问&#…

CSS小记录

1.让图文不可复制 -webkit-user-select: none; -ms-user-select: none; -moz-user-select: none; -khtml-user-select: none; user-select: none; 2.让图片垂直居中 .Logo{height: 109px;line-height: 109px;} .Logo img{vertical-align: middle;} 3.行内块级元素垂直居中&…

Java如何避免重量级锁,Java 中锁是如何一步步膨胀的(偏向锁、轻量级锁、重量级锁)...

文章目录重量级锁(Mutex Lock)偏向锁(比较 ThreadID)偏向锁获取过程偏向锁的释放轻量级锁(自旋)轻量级锁的加锁过程轻量级锁的释放总结重量级锁(Mutex Lock)Synchronized 是通过对象内部的一个叫做监视器锁(monitor)来实现的。但是监视器锁本质又是依赖于底层的操作系统的 Mute…

使用镜像源安装EASY_INSTALL和PIP教程

使用easy_install和pip可以让python的模块的安装和管理变得非常方便。我一般在新的Linux系统上&#xff0c;先easy_install pip然后就用pip安装其他的模块了。 不过&#xff0c;在国内用官方的pypi源&#xff08;https://pypi.python.org/simple&#xff09;一般比较慢&#xf…

Flexbox布局

Flexbox布局 刚开始接触flex布局的时候&#xff0c;只知道它可以用来使子元素水平垂直居中&#xff0c;代码最为简洁好用。 .container {display: flex;justify-content: center;align-items: center; } 当然不仅仅是居中问题&#xff0c;flexbox能做的事情大多&#xf…

臭名昭著的Java错误和陷阱

在2000年&#xff0c;我上大学&#xff0c;濒临选择一种语言来发展自己的职业。 Java尚未成为主流&#xff0c;但很受人们欢迎。 与静态html页面相比&#xff0c;小应用程序&#xff08;尚未破碎&#xff09;花哨且富有光泽。 Swing不是构建桌面应用程序的不错选择。 J2EE越来越…