获得更好的性能附加字符串比通过标准Java stringbuilder.append

时间:2009-11-17 17:51:12

标签: java performance stringbuilder

作为填充搜索引擎的过程的一部分,我也填充了Berekely-DB值存储。每晚重复此过程,此时每晚总运行时间的+/- 60%是由创建要插入值存储的值引起的(因此不包括实际插入Berekely-DB的时间和导致的时间由Berekely客户

这些值是通过为每个键分配一个stringbuilder创建的,并且平均将大约1000个字符串附加到这样的stringbuilder。结果值平均约为10k。 我想知道这是否可以更有效地完成,因为: - (平均而言)每个Stringbuilders附加的1000个字符串具有固定长度:即:每个字符串具有相同的长度,并且此长度在前面已知) - 所有字符串都附加到末尾。

例如,将char []或characterStream / writer更换为stringbuilder会更高效吗?这样我就可以保留并索引在char []中写入的位置。

谢谢, 吉尔特-扬

4 个答案:

答案 0 :(得分:5)

您可以创建具有更高初始容量的字符串构建器,以减少调整大小,即有一个允许您说出的构造函数

int SIZE=10000;
StringBuilder b = new StringBuilder(SIZE);

我希望手动juggling char []和索引在这方面不会有太大改进,因为(我假设)这就是StringBuilder已经为你做的了。

答案 1 :(得分:0)

这1000个字符串来自哪里?我很难相信这1000个对象的创建时间并不能完全缩短StringBuilder的摊销所需的时间。

答案 2 :(得分:0)

您应该尝试ropes。该网站的细节很少,但有一篇很棒的文章here有更好的描述和一些好benchmarks comparing append performance

我实际上并没有使用绳索包,没有足够好的借口。但看起来很有希望。

修改:其他基准信息

我从绳索文章下载了PerformanceTest类,并在StringBuilder之外添加了StringBuffer的测试。 StringBuilder的性能提升似乎可以忽略不计。

我从绳索文章下载了测试代码,并将测试更改为包含StringBuilderStringBuffer

Append plan length: 260
[StringBuilder] Average=     117,146,000 ns Median=     114,717,000ns
[StringBuffer]  Average=     117,624,400 ns Median=     115,552,000ns
[Rope]          Average=         484,600 ns Median=         483,000ns

Append plan length: 300
[StringBuilder] Average=     178,329,000 ns Median=     178,009,000ns
[StringBuffer]  Average=     217,147,800 ns Median=     216,819,000ns
[Rope]          Average=         252,800 ns Median=         253,000ns

Append plan length: 500
[StringBuilder] Average=     221,356,200 ns Median=     214,435,000ns
[StringBuffer]  Average=     227,432,200 ns Median=     219,650,000ns
[Rope]          Average=         510,000 ns Median=         507,000ns

StringBuilder和StringBuffer之间的区别并不是那么好。对于手头的任务,Ropes在这里看起来很明显。

答案 3 :(得分:0)

修订版III:

如果StringBuilders中的字符串连接过长,也许是你的 记忆非常充实。所以我们的目标是在不咀嚼的情况下实现字符串连接 记忆力很强希望节省的CPU时间将自动完成。

我的计划是这样的:而不是将这些子串连接成一个长的 StringBuilder,你可以构建一个引用列表(预先存在) 字符串。引用列表应短于子串的总和 因此消耗更少的记忆。

只有当它成为存储大字符串的时候,我们才能连接各个部分 在一个大的StringBuilder中,拉出String,存储String,扔掉 引用String,清除StringBuilder,重复。我觉得这是一个 精彩的解决方案!

然而,来自 this article from 2002,数组中的String引用,可能同样在 一个ArrayList,占用了8个字节! A recent StackOverflow post证实这仍然是这样。因此,列表 对10字节字符串的引用每个字符串只保存2个字节。因此,我提出我的 “解决方案”作为类似问题的可能性,但我没有看到这一点 问题是能够从中受益。