以下Jsoup代码连接容器els
中所有元素的文本:
for (Element el : els)
entireText += el.text();
在一个包含~64个元素的容器中,每个元素包含~1KB(整个文本总共约64KB),这个简单的循环在典型的低端Android手机上大约需要 8秒。
这种缓慢的性能令我感到惊讶,因为我认为Java编译器会将A + B + C
等表达式替换为new StringBuilder(A).append(B).append(C).toString()
。
情况不是这样吗?
我错过了什么?
答案 0 :(得分:12)
这种缓慢的表现令我惊讶,因为我在... Java编译器替换A + B + C等表达式的印象 使用新的StringBuilder(A).append(B).append(C).toString()。
因此编译器会创建代码:
for (Element el : els)
entireText = new StringBuilder(entireText).append(el.text()).toString();
您需要在循环外创建StringBuilder并手动附加到它。
答案 1 :(得分:4)
这里的问题是你的第一次迭代会创建一个1k String,第二次创建一个2k String,第三次创建一个3k String,...
每个字符串都需要创建前一个字符串的副本。所以你的第一次迭代复制1k文本,第二次复制2k,第三次复制3k,...
因此每次迭代都比前一次迭代慢,最后一次迭代分配64k缓冲区并复制64k。
使用StringBuilder
(如@mlk所示)意味着您只需要分配64k一次(不完全,但足够接近)并且仅复制64k数据(而不是64k + 63k + 62k + 61k) + 60K + ...)。