java 将字符串连接成 StringBuilder
我有一个遗留的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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
不,这不是性能问题。例如,如果您内联连接字符串(就像您所展示的那样)而不是使用循环,则编译器会自动将
+
转换为使用StringBuilder
。检查java.lang.String< 的文档/代码>
更进一步 - 编译器可能会利用这些都是字符串常量的事实,甚至在运行时之前将它们连接起来(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 aStringBuilder
. Check the documentation ofjava.lang.String
Even further - the compiler may use the fact that these are all string constants and join them even before runtime (JLS references)
像您的示例中这样的固定文字比使用 StringBuilder 更有效。
固定文字将被编译器检测到,并将被内联为单个值,因此这两行
和
将生成完全相同的字节码。
但如果连接不是通过文字而是通过函数调用完成,情况就会有所不同。
当您需要动态追加字符串时,首选 StringBuilder 而不是 StringBuffer,因为它不同步,因此速度稍快。
这是示例字节码:
这些类的生成字节码是:
正如您所看到的,两个变量的处理方式相同。
我不认为这属于语言规范,因为这“只是”编译器优化。
不同的编译器(我使用的是 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
and
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:
the generated bytecode for these classes is:
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.
实际上,编译器已经在最新版本的 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
只是常量字符串连接在编译时进行了优化,而且很简单。问题是当你做一些不那么琐碎的事情时:
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