问题
The following Jsoup code concatenates the text of all elements in container els
:
for (Element el : els)
entireText += el.text();
On a container with ~64 elements, each containing ~1KB (totaling in entireText being ~64KB), this simple loop takes about 8 seconds on a typical low-end Android phone.
This slow performance kind of surprises me because I was under the impression that Java compilers substitute expressions like A + B + C
with new StringBuilder(A).append(B).append(C).toString()
.
Is that not the case?
What am I missing?
回答1:
This slow performance kind of surprises me because I was under the impression that Java compilers substitute expressions like A + B + C with new StringBuilder(A).append(B).append(C).toString().
And so the compiler creates the code:
for (Element el : els)
entireText = new StringBuilder(entireText).append(el.text()).toString();
You will need to create the StringBuilder outside the loop and append to it manually.
回答2:
The problem here is that your first iteration creates one 1k String, the second creates a 2k String, the third creates a 3k String, ...
And each String requires creating a copy of the previous one. So your first iteration copies 1k text, the second copies 2k, the third copies 3k, ...
So each iteration is slower than the previous one and your last iteration allocates a 64k buffer and copies 64k.
Using a StringBuilder
(as @mlk showed) means you pretty much just allocate 64k once (not quite, but close enough) and only copy 64k data in total (as opposed to 64k+63k+62k+61k+60k+...).
来源:https://stackoverflow.com/questions/11311234/java-compiler-doesnt-optimize-string-concatenation-automatically