3

次のJsoupコードは、 container 内のすべての要素のテキストを連結しますels

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

最大 64 個の要素があり、それぞれに最大 1 KB (テキスト全体で合計すると最大 64 KB) のコンテナーでは、この単純なループは、典型的なローエンドの Android フォンで約8 秒かかります。

Java コンパイラが のような式A + B + Cnew StringBuilder(A).append(B).append(C).toString().

そうではありませんか?

私は何が欠けていますか?

4

2 に答える 2

12

Java コンパイラが A + B + C のような式を new StringBuilder(A).append(B).append(C).toString() に置き換えているという印象を持っていたので、この遅いパフォーマンスにはちょっと驚きました。

したがって、コンパイラはコードを作成します。

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

ループの外で StringBuilder を作成し、手動で追加する必要があります。

于 2012-07-03T12:49:54.683 に答える
4

ここでの問題は、最初の繰り返しで 1 つの 1k 文字列が作成され、2 回目で 2k 文字列が作成され、3 回目で 3k 文字列が作成され、...

また、各文字列には、前の文字列のコピーを作成する必要があります。したがって、最初の反復では 1k のテキストをコピーし、2 回目は 2k をコピーし、3 回目は 3k をコピーします...

したがって、各反復は前の反復よりも遅くなり、最後の反復では 64k のバッファーが割り当てられ、64k がコピーされます。

StringBuilder(@mlk が示したように) a を使用すると、64k を 1 回割り当てて (完全ではありませんが、十分に近い)、合計で 64k データのみをコピーすることを意味します (64k+63k+62k+61k+60k+... とは対照的に) 。

于 2012-07-03T12:52:49.190 に答える