3

以下Jsoup代码连接容器中所有元素的文本els

for (Element el : els)
  entireText += el.text();          

在具有约 64 个元素的容器上,每个元素包含约 1KB(整个文本总计约 64KB),这个简单的循环在典型的低端 Android 手机上大约需要8 秒。

这种缓慢的性能让我感到惊讶,因为我的印象是 Java 编译器会替换诸如A + B + Cwith之类的表达式new StringBuilder(A).append(B).append(C).toString()

不是这样吗?

我错过了什么?

4

2 回答 2

12

这种缓慢的性能让我感到惊讶,因为我的印象是 Java 编译器用 new StringBuilder(A).append(B).append(C).toString() 替换了像 A + B + C 这样的表达式。

所以编译器创建了代码:

for (Element el : els)
  entireText = new StringBuilder(entireText).append(el.text()).toString(); 

您将需要在循环外创建 StringBuilder 并手动附加到它。

于 2012-07-03T12:49:54.683 回答
4

这里的问题是您的第一次迭代创建了一个 1k 字符串,第二次创建了一个 2k 字符串,第三次创建了一个 3k 字符串,...

每个字符串都需要创建前一个字符串的副本。所以你的第一次迭代复制 1k 文本,第二次复制 2k,第三次复制 3k,...

所以每次迭代都比前一次慢,最后一次迭代分配一个 64k 缓冲区并复制 64k。

使用 a StringBuilder(如@mlk 所示)意味着您几乎只分配一次 64k(不完全,但足够接近)并且总共只复制 64k 数据(而不是 64k+63k+62k+61k+60k+...)。

于 2012-07-03T12:52:49.190 回答