首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >字符串连接是否经过优化以使用现有的StringBuilders?

字符串连接是否经过优化以使用现有的StringBuilders?
EN

Stack Overflow用户
提问于 2017-07-26 02:45:58
回答 3查看 3.1K关注 0票数 23

我有以下代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
StringBuilder str = new StringBuilder("foo");
for(Field f : fields){
    str.append("|" + f);
}
str.append("|" + bar);
String result = str.toString();

我知道编译器将优化字符串连接"|" + f,并将其替换为StringBuilder。但是,将创建一个新的StringBuilder,还是在Java8中使用现有的str?Java 9怎么样?

EN

回答 3

Stack Overflow用户

发布于 2017-07-26 02:57:40

默认情况下,java-9中没有用于字符串连接的StringBuilder;这是一个运行时决定如何通过invokedynamic进行连接。默认策略不是StringBuilder::append策略。

您还可以阅读更多的here

在java-8下,将创建一个新的字节码(非常容易发现invokespecial // Method java/lang/StringBuilder."<init>":()V在已编译的字节码中出现的两个地方)。

另外,您也有关于append.append...的建议;请注意,这比sb.append ... sb.append好得多,而here就是其中的原因。

票数 23
EN

Stack Overflow用户

发布于 2017-07-26 03:10:10

当字符串连接优化由Java编译器执行时,您可以通过解压缩字节代码来了解它所做的事情:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ cat Test.java
interface Field {}

public class Test {

    static String toString(Field[] fields, Object bar) {
        StringBuilder str = new StringBuilder("foo");
        for(Field f : fields){
            str.append("|" + f);
        }
        str.append("|" + bar);
        return str.toString();
    }
}
$ javac Test.java
$ javap -c Test.class
Compiled from "Test.java"
public class stackoverflow.Test {
  public stackoverflow.Test();
    Code:
       0: aload_0
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V
       4: return

  static java.lang.String toString(stackoverflow.Field[], java.lang.Object);
    Code:
       0: new           #16                 // class java/lang/StringBuilder
       3: dup
       4: ldc           #18                 // String foo
       6: invokespecial #20                 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
       9: astore_2
      10: aload_0
      11: dup
      12: astore        6
      14: arraylength
      15: istore        5
      17: iconst_0
      18: istore        4
      20: goto          53
      23: aload         6
      25: iload         4
      27: aaload
      28: astore_3
      29: aload_2
      30: new           #16                 // class java/lang/StringBuilder
      33: dup
      34: ldc           #23                 // String |
      36: invokespecial #20                 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
      39: aload_3
      40: invokevirtual #25                 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
      43: invokevirtual #29                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      46: invokevirtual #32                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      49: pop
      50: iinc          4, 1
      53: iload         4
      55: iload         5
      57: if_icmplt     23
      60: aload_2
      61: new           #16                 // class java/lang/StringBuilder
      64: dup
      65: ldc           #23                 // String |
      67: invokespecial #20                 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
      70: aload_1
      71: invokevirtual #25                 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
      74: invokevirtual #29                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      77: invokevirtual #32                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      80: pop
      81: aload_2
      82: invokevirtual #29                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      85: areturn
}

如您所见,代码在StringBuilder 3 places中调用构造函数(Method java/lang/StringBuilder."<init>":),因此将在每次迭代中创建新的StringBuilders (除非实时编译器执行奇特的优化)。

这不太可能是一个显著的性能问题,但在不太可能的情况下,您可以很容易地通过重写到

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
str.append("|").append(f);
票数 8
EN

Stack Overflow用户

发布于 2017-07-26 03:32:35

根据Java9API文档

实现注意事项: 只要编译器最终符合Java规范,字符串连接操作符的实现将由Java编译器自行决定。例如,javac编译器可能使用StringBuffer、StringBuilder或java.lang.invoke.StringConcatFactory实现操作符,这取决于JDK版本。字符串转换的实现通常是通过toString方法实现的,该方法由对象定义,并由Java的所有类继承。

根据这一点,它将在每次迭代时创建一个新的字符串生成器。因此,正如这里的几个人所提到的,使用下面的代码是更优化的

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
append("|").append(f)

您可以找到API文档here

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45324692

复制
相关文章
Python判断字符串是否以字母开头
直接上代码吧 import re rule = re.compile('^[a-zA-z]{1}.*$') str='123' if rule.match(str) is None: print(str+'不以字母开头') else: print(str+'以字母开头') str2='a12' if rule.match(str2) is None: print(str2+'不以字母开头') else: print(str2+'以字母开头')
week
2020/03/12
3K0
Linux kernel 的设计是否已经过时?
Linux 多年来取得的成绩毋庸多言。但最近,reddit 上有人发起了一个话题,想知道 Linux 的内核设计是否已经过时,并得到了一些有趣的答案。 这位 Ronis_BR 的用户提问大致如下: Linux 是在 1992 年启动的,一些特性到现在都没有改变。我猜想最新的操作系统内核设计技术(如果存在…)应该较之前有很大的进步。那 Linux 内核是否已经过时? 与 Windows、macOS、FreeBSD 内核的设计相比,Linux 内核的设计有没有在哪些方面比较先进?(注意,重点是设计的先进,
小小科
2018/05/03
1.2K0
使用连接组优化连接 (IM 6)
连接(Join)是数据仓库工作负载的一个组成部分。 当连接的表存储在内存中时,IM列存储增强了连接的性能。
Yunjie Ge
2022/04/23
1.3K0
使用连接组优化连接 (IM 6)
在Entity Framework中重用现有的数据库连接字符串
本文转载:http://www.cnblogs.com/dudu/archive/2011/01/29/entity_framework_connection_string.html
跟着阿笨一起玩NET
2018/09/19
1.1K0
在Entity Framework中重用现有的数据库连接字符串
在Entity Framework中重用现有的数据库连接字符串
Entity Framework使用的连接字符串与ADO.NET是不同的,见下图:
跟着阿笨一起玩NET
2018/09/19
1.3K0
在Entity Framework中重用现有的数据库连接字符串
winscp连接centos7出现拒绝连接
1.编辑 /etc/ssh/sshd_config文件: sudo vi /etc/ssh/sshd_config
全栈程序员站长
2022/09/30
1.9K0
深度学习是否以蛮力取胜?
Vladimir Vapnik 介绍: Vladimir Vapnik 被称为统计学习理论之父,他出生于俄罗斯,1990 年底移居美国,在美国贝尔实验室一直工作到 2002 年,之后加入了普林斯顿的 NEC 实验室机器学习研究组,同时任哥伦比亚大学特聘教授。2006 年,Vladimir 称为美国工程院院士。2014年 Vladimir Vapnik 加入 Facebook 人工智能实验室。Vladimir Vapnik 在机器学习上有很多奠基之作,例如 Vapnik–Chervonenkis 理论,Vla
新智元
2018/03/13
1.2K0
深度学习是否以蛮力取胜?
java判断字符串是否以字母开头,java判断字符串第一个字符是否是字母
(1).方式一,最常用的方法,但是有坑,因为遇到中文就判断错误String str = "Hello World";if (Character.isLetter(str.charAt(0))) {    System.out.println("第一个字符是字母");} else {    System.out.println("第一个字符不是字母");}(2).方式二,正则性能差String str = "你好,Hello World";if (str.matches("^[a-zA-Z].*")) { 
高久峰
2023/05/14
2K0
【讨论】Linux kernel 的设计是否已经过时?微内核?
余承东认为,当前,Android/Linux 内核代码庞大且冗余,比如 Android 代码就有一亿行,Linux 内核代码也有 2000 万行,很难保证不同终端的体验流畅。鸿蒙 OS 采用全新的微内核设计,拥有更强的安全特性和低时延等特点。微内核设计的基本思想是简化内核功能,在内核之外的用户态尽可能多地实现系统服务,同时加入相互之间的安全保护。微内核只提供最基础的服务,比如多进程调度和多进程通信等。
Linux阅码场
2019/08/16
2.2K0
中国的程序员群体是否已经过多了
相信尚在学校的同学和想转行的同道多少都会有类似的担心。下面仅就我自己的一些经验和观察来简单聊聊。
木鸟杂记
2022/03/31
2780
容器时代,服务器虚拟化是否已经过时?
IT基础架构发展的几个阶段是什么? 在近20年的时间里,IT基础架构经历了三个大的阶段,分别是:硬件定义数据中心(HDDC)、软件定义数据中心(SDDC)、容器时代。 在硬件定义数据中心时代,不同大型机/小型机厂商的操作系统和硬件紧耦合,应用在不同业务系统上迁移难度非常大。 随着X86服务器以及虚拟化技术的普及,操作系统与底层服务器硬件实现松耦合,IT界进入”软件定义数据中心“的时代。 随着技术的发展,IT进入了“应用为王”时代。在新的时代,能否做到应用与操作系统松耦合呢?让应用在不同操作系统之前实现无缝
魏新宇
2018/03/22
2.9K0
容器时代,服务器虚拟化是否已经过时?
使用MySQL的rlike判断字符串是否匹配
表user_experience_wealth_log改名为user_experience_wealth_log_new,该表涉及若干存储过程。为了避免遗漏,需要确认所有相关过程都做了修改,验证方法为不存在包含user_experience_wealth_log的存储过程。
用户1148526
2020/04/30
1.7K0
VBA判断是否连接公司内网/是否联网(Excel)
Function 测网(url) On Error Resume Next cmdping = "ping " & url & " -n 1" Set oExec = CreateObject("Wscript.shell").exec(cmdping) Do Until oExec.stdout.AtEndOfStream strline = strline & oExec.stdout.readline() & Chr(13) Loop 测网 = 0 If InStr(strline,
林万程
2018/06/20
2.3K0
ABB DI93A 以采用现有的现场总线
考虑到工厂类型的巨大数量和多样性、所涉及的各种型号(尤其是规模),网络系统应该易于扩展且成本低廉,并且应该提供冗余,同时能够处理加工工业的特定要求,包括恶劣环境或潜在爆炸性环境中的操作。这以太网-APL工程指南概述了以太网-APL网络的多种网络拓扑,尽管所有拓扑的以太网-APL杂散环境都是相同的。以太网-APL设备可以通过IV类电缆(长度不超过200米)连接到交换机,并可以10 Mbps的传输速率进行通信。让我们仔细看看其中的三种变体。
用户10384942
2023/04/28
1540
ABB DI93A 以采用现有的现场总线
大数据时代,传统数据仓库技术是否已经过时?
内容来源:2017 年 10 月 21 日,深奇智慧联合创始人高扬在“PostgreSQL 2017中国技术大会”进行《基于Greenplum,postgreSQL的大型数据仓库实践》演讲分享。IT 大咖说(微信id:itdakashuo)作为独家视频合作方,经主办方和讲者审阅授权发布。
IT大咖说
2018/07/27
1.6K0
大数据时代,传统数据仓库技术是否已经过时?
大数据时代,传统数据仓库技术是否已经过时?
传统的数据仓库架构一般有由源系统、ODS、EDW、Data Mart几部分组成。源系统就是业务系统、管理系统、办公系统等等;ODS是操作数据存储;EDW是企业级数据仓库,Data Mart是数据集市。
物流IT圈
2019/07/16
2.7K0
大数据时代,传统数据仓库技术是否已经过时?
字符串连接
/* 功能:字符串连接 日期:2013-05-26 */ #include<stdio.h> #include<stdlib.h> #include<math.h>
WindCoder
2018/09/20
1.5K0
使用java连接AD域,验证账号密码是否正确
web项目中有时候客户要求我们使用ad域进行身份确认,不再另外做一套用户管理系统。其实客户就是只要一套账号可以访问所有的OA,CRM等办公系统。 这就是第三方验证。一般有AD域,Ldap,Radius,邮件服务器等。最常用的要数AD域了。因为window系统在国内占据了大量的江山。做起来也很方便。 我这篇文章就是写,如何用java去实现AD域的身份验证。好了,直接看代码吧:
业余草
2019/01/21
2.8K0
使用java连接AD域,验证账号密码是否正确
java中如何使用if语句判断字符串是否相等
大家好,我是架构君,一个会写代码吟诗的架构师。今天说一说java中如何使用if语句判断字符串是否相等,希望能够帮助大家进步!!!
Java架构师必看
2022/01/17
2.9K0
java中如何使用if语句判断字符串是否相等
API网关是否真的起到了它该有的作用?
点击上方蓝色“程序猿DD”,选择“设为星标” 回复“资源”获取独家整理的学习资料! 以下内容来源 https://www.jianshu.com/p/9fab0982c6bb,部分内容稍做修改 最近看到一篇翻译一篇API网关的文章,介绍了其三种角色:API管理、集群入口控制、API网关模式,最后还讲了与服务网格的关系,通过此文可以更全面的理解API网关的作用。 原文 API Gateways are going through an identity crisis (地址如下:https://mediu
程序猿DD
2023/04/04
3580
API网关是否真的起到了它该有的作用?

相似问题

Zend_Paginator;是否经过优化?

22

C++CLI是否经过优化?

217

StringUtils for StringBuilders?

25

以大量nul字符结尾的StringBuilders

10

微观优化,它是否经过了现代浏览器的优化?

10
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文