所有
我想知道使用setLength(0)清除StringBuffer内容是否有意义。即,做得更好:
while (<some condition>)
{
stringBufferVariable = new StringBuffer(128);
stringBufferVariable.append(<something>)
.append(<more>)
... ;
Append stringBufferVariable.toString() to a file;
stringBufferVariable.setLength(0);
}
我的问题:
1>这还有比使用String对象追加内容更好的性能吗?
我不确定如何重新初始化StringBuffer变量会影响性能,从而影响问题。
请填写您的意见
[edit]:删除了关于与StringBuilder进行比较的第二个问题,因为我已经理解根据响应没有其他内容可以研究。
答案 0 :(得分:7)
如果你问是否
stringBufferVariable.append("something")
.append("more");
...
将比与+
连接更好,然后通常是。这就是这些类存在的全部原因。与更新char
数组中的值相比,对象创建非常昂贵。
在大多数情况下,如果不是所有编译器现在都将字符串连接转换为在str = "something" + "more" + "...";
这样的简单情况下使用StringBuilder。我可以看到的唯一性能差异是编译器没有设置初始大小的优势。基准测试将告诉您差异是否足够重要。使用+
会使代码更易读。
从我读过的内容来看,编译器显然不能优化循环中的连接,就像
一样String str = "";
for (int i = 0; i < 10000; i++) {
str = str + i + ",";
}
因此,在这些情况下,您仍然希望显式使用StringBuilder。
StringBuilder
是{p> StringBuffer
不是线程安全的,但它们在其他方面是相同的。在StringBuffer中执行的同步使其更慢,因此StringBuilder
更快,除非您需要同步,否则应该使用它。
setLength
吗?您的示例当前编写的方式我不认为对setLength
的调用会给您带来任何好处,因为您在每次循环中都创建了一个新的StringBuffer。你真正应该做的是
StringBuilder sb = new StringBuilder(128);
while (<some condition>) {
sb.append(<something>)
.append(<more>)
... ;
// Append stringBufferVariable.toString() to a file;
sb.setLength(0);
}
这可以避免不必要的对象创建,setLength只会在这种情况下更新内部int
变量。
答案 1 :(得分:3)
我只关注这部分问题。 (之前已经多次询问并回答了其他部分。)
我想知道使用setLength(0)清除StringBuffer内容是否有意义。
这取决于您使用的Java类库。在Java的一些较旧的Sun版本中,StringBuffer.toString()是在假设调用sb.toString()
是缓冲区完成的最后一件事的情况下实现的。 StringBuffer的原始后备数组成为toString()
返回的String的一部分。随后尝试使用StringBuffer导致通过复制String内容创建并初始化新的后备阵列。因此,重用StringBuffer就像你的代码试图做的那样实际上会使应用程序变慢。
使用Java 1.5及更高版本,更好的编码方法如下:
bufferedWriter.append(stringBufferVariable);
stringBufferVariable.setLength(0);
这应该直接将StringBuilder中的字符复制到文件缓冲区中,而无需创建临时String。假设StringBuffer声明在循环之外,则setLength(0)允许您重用缓冲区。
最后,如果您有证据证明这部分代码是(或可能是)瓶颈,那么您应该只担心所有这些。 “过早的优化是所有邪恶的根源”,等等,等等。
答案 2 :(得分:1)
对于问题2,StringBuilder的性能优于StringBuffer。 StringBuffer是线程安全的,意味着方法是同步的。字符串生成器未同步。因此,如果您拥有的代码将由一个线程运行,那么StringBuilder将具有更好的性能,因为它没有执行同步的开销。
正如camickr建议的那样,请查看StringBuffer和StringBuilder的API以获取更多信息。
您也可能对这篇文章感兴趣:The Sad Tragedy of Micro-Optimization Theater
答案 3 :(得分:0)
1&gt;这还有比使用String对象附加内容更好的性能吗?
是的,因为你不断创建新的字符串对象,所以连接字符串很慢。
2&gt;如果在这里使用StringBuilder会比StringBuffer更好,那么为什么呢?
您是否阅读过StringBuilder和/或StringBuffer的API描述?这是在那里发布的。
我不确定如何重新初始化StringBuffer变量会影响性能,从而影响问题。
好好创建一个测试程序。创建一个每次都创建一个新StringBuffer / Builder的测试。然后重新运行测试,只需将字符重置为0,然后比较时间。
答案 4 :(得分:0)
也许我在你的问题中误解了一些内容...如果你只是在每次迭代开始时创建一个新的长度,为什么你将长度设置为0?
假设变量是方法的局部变量,或者如果多个线程在方法之外声明它将不会被多个线程使用(如果它在方法之外,你的代码可能有问题),那么就把它变成一个StringBuilder的。
如果在循环之外声明StringBuilder,那么每次进入循环时都不需要创建一个新的,但是你想在循环结束时将长度设置为0。
如果在循环内部声明StringBuilder,则不需要在循环结束时将长度设置为0.
很可能在循环外声明并将长度设置为0会更快,但我会测量两者,如果没有大的差异,则在循环内声明变量。优良作法是限制变量的范围。
答案 5 :(得分:-1)
烨! setLength(0)
是个好主意!这就是它的用途。更快捷的做法是放弃stringBuffer
&amp;做一个新的。它的速度更快,无法说出内存效率:)