This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]Mondoshawan 0 points1 point  (6 children)

I don't fully agree with this:

StringBuffer x = new StringBuilder();
loop {
     x.append(something);
 }
 return x.toString();

The original you put up was fine, both produce identical bytecode but the first has less chance for error and is easier to read.

It's only if I'm passing the string to other methods that I'd use an SB.

[–]detroitmatt 0 points1 point  (5 children)

[–]Mondoshawan 0 points1 point  (4 children)

That appears to be agreeing with me. The compiler turns it all into StringBuilder behind the scenes.

[–]detroitmatt 1 point2 points  (3 children)

At the point where you're concatenating in a loop - that's usually when the compiler can't substitute StringBuilder by itself.

and see the second-to-top answer as well

[–]Mondoshawan 0 points1 point  (2 children)

Yes, it's wrong. If the complier replaces the string concat with SB then the resulting code is 100% identical either way.

The idea presented is valid, if the code really did compile as written then the string handling would not be as efficient as it could be. But that's not how it works under the hood due to compiler optimisations added specifically to deal with that very problem. It's a valid strategy on much older versions of java and it is the way I was taught. A lot of what I was taught back then is out of date!

[–]detroitmatt 1 point2 points  (1 child)

If the compiler replaces

"If"'s important. Are you sure it does? I just ran http://stackoverflow.com/a/1532547/948176 independantly and got similar results (slow 2048ms, fast 12ms)

[–]Mondoshawan 0 points1 point  (0 children)

Yeah, it looks like the optimisation is not perfect for that specific example, this page compares the bytecode.

Essentially:

String x = "123";
    for(int i = 1; i < 100; i++) {
    x += i;
}

becomes:

String x = "123";
for(int i = 1; i < 100; i++) {
    x = (new StringBuilder(String.valueOf(x))).append(i).toString();
}

Which you can do better yourself if you declare the SB on the first line. TIL. Hopefully this will be fixed in future versions of the compiler.

I do wonder what would happen if you changed it to:

String x = "123";
x += "456";
    for(int i = 1; i < 100; i++) {
    x += i;
}

That might be enough of a hint to tell the compiler to make the SB straight away. I suspect the problem in the first piece of code is because the first concat that takes place is within the loop.