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,一经查实,立即删除!

相关文章

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} };//四棱…

WSO2 ESB的一种消息传递方式

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

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

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

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

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

用CSS3来代替JS实现交互

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

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

Hadoop如何工作? HDFS案例研究

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

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

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

Flexbox布局

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

CSS_常见布局

1.一列布局——常用于网站首页。 html&#xff1a; 1 <div class"top"></div> 2 <div class"main"></div> 3 <div classfoot></div> css&#xff1a; 1 body{2 margin:0;3 padding: 0;4 …

会员系统用php框架,代码基地会员中心的PHP签到系统结合thinkphp框架

分享代码基地会员中心的PHP签到系统&#xff0c;PHP很漂亮的签到界面。签到后&#xff0c;会有不同颜色区分。附带PHP签到源码带安装说明和详细注释。(详细查看https://www.daimajidi.com/deal/574)JS:function getUrl(strs) {var url "/demo/1563064903/" strs;re…

Spring MVC:表单处理卷。 1个

Spring MVC是Spring Framework的一部分&#xff0c;其主要目的是使Web开发更加简单&#xff0c;便捷和轻松。 与表单的交互是或多或少现代Web应用程序的一部分。 Spring MVC允许您以非常严格和简单的方式执行各种形式的活动。 在本文中&#xff0c;您将在Spring MVC的帮助下阅读…

Java监视器绑定的超人

这是超人生活中的黑暗时期。 乔尔艾尔&#xff08;Jor-El&#xff09;希望他继续航行&#xff0c;为他的最终命运做好准备。 然而&#xff0c;地球面临着世界末日&#xff0c;正义联盟需要他们的钢铁侠行动来拯救世界。 但是由于我们只有一个超人&#xff0c;您不能同时做这两个…

CSS实现垂直居中的5种方法

利用 CSS 来实现对象的垂直居中有许多不同的方法&#xff0c;比较难的是选择那个正确的方法。我下面说明一下我看到的好的方法和怎么来创建一个好的居中网站。 使用 CSS 实现垂直居中并不容易。有些方法在一些浏览器中无效。下面我们看一下使对象垂直集中的5种不同方法&#xf…

尝试使用jBPM Console NG(测试版)

大家好&#xff01; 这是关于jBPM Console NG的另一篇文章。 经过6个月的辛苦工作&#xff0c;我很高兴为开发者社区撰写这篇文章&#xff0c;以进行尝试。 在这篇文章中&#xff0c;我将解释如何从源代码构建应用程序。 这背后的主要思想是知道如何在测试过程中设置环境并修改…

php在window磁盘管理,Windows Server 2008R2设置磁盘阵列

RAID(独立硬盘冗余阵列)指用多个硬盘组成一个高性能、大容量的一个硬盘组合。独立硬盘冗余阵列(RAID, Redundant Array of Independent Disks)&#xff0c;旧称廉价磁盘冗余阵列(RedundantArray of Inexpensive Disks)&#xff0c;简称硬盘阵列。其基本思想就是把多个相对便宜的…

解决Error: ENOENT: no such file or directory, scandir 安装node-sass报错

新项目开发需要安装依赖&#xff0c;但是安装完之后通过gulp运行项目&#xff0c;产生了一下的报错&#xff1a; 解决方案是执行一些方法&#xff1a; npm rebuild node-sass可是有时就是网络问题导致上面命令安装失败&#xff0c;查下失败提示&#xff0c;有可能是&#xff1a…

系统讲解CSS,前端开发最神奇的技术,新手的你一定不能错过

前面小编带领大家重温了前端开发中最基本的HTML语言。如果你已经掌握了这门语言&#xff0c;那么恭喜你&#xff0c;可以去深入了解CSS技术了。CSS技术最主要的功能就是弥补HTML标记对在页面中显示外观的不足&#xff0c;对这些标记对的默认外观进行美化。从本文开始&#xff0…

JUnit和Mockito合作

这次&#xff0c;我想对测试框架Mockito进行概述。 毫无疑问&#xff0c;这是用于测试Java代码的最受欢迎的工具之一。 我已经对Mockito的竞争对手EasyMock进行了概述。 这篇文章将基于有关EasyMock的示例应用程序。 我的意思是代表咖啡机功能的类。 用Mockito准备测试 通常&a…