java 将字符串连接成 StringBuilder

发布于 2024-10-27 04:08:02 字数 567 浏览 1 评论 0原文

我有一个遗留的Java文件,它使用字符串连接来构建巨大的字符串对象。这是一个严重的性能问题。是否有一种方法可以执行以下操作

String test="I am a very bad programmer"
+"to use concatenation"
+"Instead of StringBuilder"
+" or StringBuffer";

StringBuilder strBuilder= new StringBuilder();
strBuilder.append("I am a bad programmer");
strBuilder.append("to use concatenation");
strBuilder.append("Instead of StringBuilder");
strBuilder.append(" or StringBuffer");
String str= strBuilder.toString();

基本上我需要一个java中的存根来提供字符串实例化作为输入和转换为 StringBuilder。过去有人尝试过这个吗?

I have a legacy Java file which uses String concatenation to build huge String objects.Its a serious performance issue.Is there a method as such which does the following

String test="I am a very bad programmer"
+"to use concatenation"
+"Instead of StringBuilder"
+" or StringBuffer";

to

StringBuilder strBuilder= new StringBuilder();
strBuilder.append("I am a bad programmer");
strBuilder.append("to use concatenation");
strBuilder.append("Instead of StringBuilder");
strBuilder.append(" or StringBuffer");
String str= strBuilder.toString();

basically I need a stub in java just to give a the String instantiation as input and convert into StringBuilder.Anybody tried this in the past?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

独留℉清风醉 2024-11-03 04:08:02

不,这不是性能问题。例如,如果您内联连接字符串(就像您所展示的那样)而不是使用循环,则编译器会自动将 + 转换为使用 StringBuilder。检查 java.lang.String< 的文档/代码>

Java 语言为字符串连接运算符 (+) 以及将其他对象转换为字符串提供了特殊支持。字符串连接是通过StringBuilder(或StringBuffer)类及其append方法实现的。字符串转换是通过toString方法实现的,该方法由Object定义,并被Java中的所有类继承。有关字符串连接和转换的更多信息,请参阅 Gosling、Joy 和 Steele 的《Java 语言规范》。

更进一步 - 编译器可能会利用这些都是字符串常量的事实,甚至在运行时之前将它们连接起来(JLS 参考文献)

No, it isn't a performance issue. If you are concatenating the string inline (just like you showed) rather than using a loop for example, then the compiler automatically transforms the + to using a StringBuilder. Check the documentation of java.lang.String

The Java language provides special support for the string concatenation operator ( + ), and for conversion of other objects to strings. String concatenation is implemented through the StringBuilder(or StringBuffer) class and its append method. String conversions are implemented through the method toString, defined by Object and inherited by all classes in Java. For additional information on string concatenation and conversion, see Gosling, Joy, and Steele, The Java Language Specification.

Even further - the compiler may use the fact that these are all string constants and join them even before runtime (JLS references)

暮年 2024-11-03 04:08:02

像您的示例中这样的固定文字比使用 StringBuilder 更有效。

固定文字将被编译器检测到,并将被内联为单个值,因此这两行

String s = "one" + "two" + "three";

String s = "onetwothree";

将生成完全相同的字节码。

但如果连接不是通过文字而是通过函数调用完成,情况就会有所不同。

当您需要动态追加字符串时,首选 StringBuilder 而不是 StringBuffer,因为它不同步,因此速度稍快。

这是示例字节码:

public class Test
{
   private String s = "one" + "two" + "three";
}

public class Test2
{
   private String s2 = "onetwothree";
}

这些类的生成字节码是:

c:\Temp>javap -c Test
Compiled from "Test.java"
public class Test extends java.lang.Object{
public Test();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."":()V
   4:   aload_0
   5:   ldc     #2; //String onetwothree
   7:   putfield        #3; //Field s:Ljava/lang/String;
   10:  return
}
c:\Temp>javap -c Test2
Compiled from "Test2.java"
public class Test2 extends java.lang.Object{
public Test2();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."":()V
   4:   aload_0
   5:   ldc     #2; //String onetwothree
   7:   putfield        #3; //Field s:Ljava/lang/String;
   10:  return
}

正如您所看到的,两个变量的处理方式相同。

我不认为这属于语言规范,因为这“只是”编译器优化。

不同的编译器(我使用的是 Sun 编译器)可能会做完全不同的事情 - 只要行为不改变就可以。

A fixed literal like in your example is more efficient than using a StringBuilder.

The fixed literal will be detected by the compiler and will be inlined as a single value, so the two lines

String s = "one" + "two" + "three";

and

String s = "onetwothree";

will generate exactly the same bytecode.

The picture is different though if the concatenation is not done with literals but with function calls.

When you need to append strings dynamically, prefer StringBuilder over StringBuffer because it is slightly faster as it is not synchronized.

Here is the example bytecode:

public class Test
{
   private String s = "one" + "two" + "three";
}

public class Test2
{
   private String s2 = "onetwothree";
}

the generated bytecode for these classes is:

c:\Temp>javap -c Test
Compiled from "Test.java"
public class Test extends java.lang.Object{
public Test();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."":()V
   4:   aload_0
   5:   ldc     #2; //String onetwothree
   7:   putfield        #3; //Field s:Ljava/lang/String;
   10:  return
}
c:\Temp>javap -c Test2
Compiled from "Test2.java"
public class Test2 extends java.lang.Object{
public Test2();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."":()V
   4:   aload_0
   5:   ldc     #2; //String onetwothree
   7:   putfield        #3; //Field s:Ljava/lang/String;
   10:  return
}

As you can see both variables are treated the same way.

I don't think this belongs to the language specification, as this is "just" a compiler optimization.

A different compiler (I was using the Sun compiler) might be doing something completely different - which is OK as long as the behaviour doesn't change.

巡山小妖精 2024-11-03 04:08:02

实际上,编译器已经在最新版本的 Java 中为您应用了这种优化(我认为至少从 1.5 开始)。

当 Java 编译器看到多个字符串时会发生什么串联在一行中?

http ://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.18.1.2

Actually the compiler already applies that optimization for you in the latest versions of Java (at least from 1.5, I think).

What happens when Java Compiler sees many String concatenations in one line?

http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.18.1.2

终难遇 2024-11-03 04:08:02

只是常量字符串连接在编译时进行了优化,而且很简单。问题是当你做一些不那么琐碎的事情时:

String example1 = "Prefix" + variableString1 + "Suffix";

最坏的情况是每次迭代都需要创建一个新字符串的循环。由于这对于文件的缓冲读取很常见,因此您可能会重新创建非常大的字符串,这是我最近遇到的问题。

虽然我明白为什么你想做你所做的事情,但代码的结构太不同了,不能直接插入和替换,并且编辑代码的脚本必须非常先进才能处理所有参考。也许有一种使用匿名内部类的方法,可以让您保留相同的字符串引用,但将实际的构造包装在字符串构建器中。这可能与优化器已经做的没有什么不同

Just constant string contatenation is optimised at compile time, and is trivial. The issue is when you do something less trivial:

String example1 = "Prefix" + variableString1 + "Suffix";

the worst case is loops with appending where every iteration needs to create a new string. Since this is common for buffered reads of files you can get very big strings being recreated, a problem I had recently.

While I see why you'd want to do what you do, the structures of the code are too different to just drop in and replace, and a script to edit the code would have to be quite advanced to be able to deal with all the references. Maybe there is a way with annonomous inner classes though that can let you keep the same string reference but wrap the actual construction in string builders. It's probably no different than what the optimiser already does though

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文