• MadPad (unregistered)
    sb.append("onkeydown=\"" + id + ".check(event,this," + String.valueOf(column) + "," + String.valueOf(row) + ")\" ");
    Superb! With optimization like that who needs faster processors
  • Ralf Engels (unregistered)

    Isn't it a little bit stupid to use "append" and then have String contatinations inside the parameters?

    That's a perfect case of "measure, optimize, measure". After all this whole crap might prevent the compiler from optimizing the thing.

  • Hit (unregistered) in reply to Ralf Engels
    Ralf Engels:
    Isn't it a little bit stupid to use "append" and then have String contatinations inside the parameters?

    Actually, the (Java/C#) compiler is smart enough to take all concatinations like this:

    "foo" + "foo2" + "foo3"...

    and turn them into

    StringBuffer _temp = new StringBuffer();

    _temp.append("foo").append("foo2").append("foo3")...

    and then return the String object from that.

    Which doesn't make this any less of a WTF, because once again we have idiotic "optimization" for a process that likely doesn't need it and will simply make for harder maintenance.

  • MrBester (unregistered)

    also: onClick isn't closed. Sometimes you just know this was aimed at IE...

    captcha: onomatopoeia. WTF? Don't you know œ is a diphthong?

  • Vector (cs)

    Oh my.

    Any more of that and a regular expression will be easier to read. :/

  • David Vallner (unregistered)

    Erght, I encountered this one in my code (i.e. code I was working with, not code I wrote) about a year ago. And rejected the thought of submitting it to the Daily WTF.

    My instance of this class of WTFery added insult to injury in that the arguments to the append() calls were only literal string constants and the whole XML nonsense would have been better off in constant or file.

  • n0ha (unregistered)

    Wow, looks really like a bit of code I wrote some years ago. Yes, I feel ashamed now :)

  • Rick (unregistered)

    Up to java 1.4

        String foo = "boo: " + id + " baa"; 
    

    and

        String bar = new StringBuffer().append("boo: ").append(id).append(" baa").toString();
    

    compiled to exactly the same bytecode. The compiler turns the string concatenations into a series of appends on a StringBuffer. In this case, using the StringBuffer construction isn't an optimization at all, just an obfuscation of the source code.

    In Java 1.5 and up, the former is actually turned into a series of appends on a StringBuilder object by the compiler, which could be more efficient in many cases. In this case, the StringBuffer construction is both an obfuscation of the source code and a potential downgrade in performance.

    When should you use a StringBuffer?

    String meep = "";
    for(Iterator i = somelonglist.iterator();i.hasNext();) {
        meep += (String)i.next();
    }
    

    is less efficient than:

    StringBuffer sb = new StringBuffer();
    for(Iterator i = somelonglist.iterator();i.hasNext();) {
        sb.append((String)i.next());
    }
    String meep = sb.toString();
    

    In the former case, the bytecode generated by the compiler is equivalent to a new StringBuffer object being created every iteration, meep being appended to it, then (String)i.next() being appended to it, and then the result being put into meep. The latter case creates one StringBuffer object, appends (String)i.next() to it every iteration, and then after finishing the loop, puts the result into meep.

  • Heinz Gorgon Mittelmacher (unregistered)

    As I recall, + is overloaded for StringBuilders and StringBuffers as well as for Strings.

  • XIU (unregistered) in reply to Hit
    Hit:
    Ralf Engels:
    Isn't it a little bit stupid to use "append" and then have String contatinations inside the parameters?

    Actually, the (Java/C#) compiler is smart enough to take all concatinations like this:

    "foo" + "foo2" + "foo3"...

    and turn them into

    StringBuffer _temp = new StringBuffer();

    _temp.append("foo").append("foo2").append("foo3")...

    and then return the String object from that.

    Which doesn't make this any less of a WTF, because once again we have idiotic "optimization" for a process that likely doesn't need it and will simply make for harder maintenance.

    The C# compiler will even take true string constants and just combine them so:

    string test = "foo1" + "foo2";

    will be compiled to

    string test = "foo1foo2";

    For up to 4 strings it will use string.Concat if you're using variables.

    The real WTF I see here is that most of the string literals could be combined. So the following code:

    sb.append("TYPE="" + TYPE + " " "); sb.append("CELL="" + CELL_TYPE + """ ");

    Should have been:

    sb.append("TYPE=""); sb.append(TYPE); sb.append(" " CELL=""); sb.append(CELL_TYPE); sb.append(""" ");

    Oh well, some people will never learn...

  • dude (unregistered)

    Btw, StringBuffer's methods are synchronized. That's the reason StringBuilder exists in Java5.

  • AstorLights (cs)

    I don't think this use of StringBuffer is a big wtf ... it looks like the author used it only to make the code more readable and didn't care about optimizations at all.

  • Richard (unregistered) in reply to XIU

    Won't the Java compiler also combine literals? so

    String a = "Foo" + "Bar" + "Baz";

    will compile to "FooBarBaz".

    In this case

    sb.append("Foo"); sb.append("Bar"); sb.append("Baz");

    is worse.

    This example

    sb.append("Foo" + a + "Bar"); sb.append("Baz" + b);

    Would require 3 StringBuffers including sb

    sb1 = new StringBuffer("Foo"); sb1.append(a); sb1.append("Bar"); sb.append(sb1.toString()); sb2 = new StringBuffer("Baz"); sb2.append(b); sb.append(sb2.toString());

    You could write it as

    sb.append("Foo"); sb.append(a); sb.append("BarBaz"); sb.append(b);

    but this IIRC is the result you get from writing

    "Foo" + a + "Bar" + "Baz" + b

    which is more readable.

    I think in very old versions of Java, back in the mid 90s, the above would have created a StringBuffer for every + sign. I don't thing that's been the case for a while.

    CAPTCHA: Waffles - sounds about right ;-)

  • Tassos Bassoukos (unregistered) in reply to MrBester

    Actually, that's Greek (???µat?p??e?a), which doesn't have the oe dipthong....

  • Tachyon (unregistered)

    Biggest WTF: not separating the model and view aspect, and appending strings instead of using templating to generate the HTML. It could be so easy when using Velocity or Freemarker, and generating the HTML out of a view template and a view model...

  • This is probably not a WTF at all. (unregistered)
    Comment held for moderation.
  • Volmarias (cs) in reply to Tassos Bassoukos

    According to my own research on this (from roughly Java 1.4), the line of code:

    "ABC" + "DEF" + "GHI" + foo + "JKL" + "MNO" + "PQR"

    would be optimized to

    StringBuilder tmp = new StringBuilder(); tmp.append("ABCDEFGHI"); tmp.append(foo); tmp.append("JKL"); tmp.append("MNO"); tmp.append("PQR"); blah = tmp.toString();

    Which is to say, the compiler was smart enough to figure out to combine the left side, but did not manage to combine the string literals on the right side which clearly went together.

    I won't say exactly why I know this, but today's code snippit is a little close to how parts of our system work (albiet far worse)

  • maratcolumn1 (cs)

    I actually see this all the time (well, many other WTFs too :().

    The real WTF is neither SDK nor Eclipse compiler bother to optimize it, although it's absolutely trivial. Good compiler could even calculate suitable argument for

    new StringBuffer(int)
    .

    Another WTF is [ code ] not working like or .

  • Mikolaj (unregistered)

    Do you guys know how String.format() performs? I like it much more than adding several Strings, or appending to StringBuilder...

  • Asd (unregistered) in reply to This is probably not a WTF at all.
    Comment held for moderation.
  • Asd (unregistered) in reply to Asd

    Oh yeah, of course some kind of template framework should be used.

  • csixty4 (unregistered)

    I think I used to work for this guy. Does he believe that XML is "nothing but specially formatted strings", and that org.w3c.dom is what wannabe programmers use to build or parse it?

    (and does he come in on Monday mornings after a long bender and throw up in his wastebasket?)

  • Viadd (unregistered)

    A diphthong is two vowel sounds glided together.

    A ligature is two typographical letter forms combined, as in œ.

    See the wiki for more details.

  • Botia (unregistered) in reply to This is probably not a WTF at all.

    I have to agree. This is not necessarily a WTF. I know that we ended up using similar code in C# and .NET 1.0 inside a loop. It improved performance 1000 fold. The performance hit (at that time at least) came from concatenating large strings, not small ones. As such, this code would have worked well.

  • trout (unregistered)

    This brings back bad memories. I worked on a site that used a similar technique, but it was originally written by an ASP (Classic) developer who was unaware of the concept of a StringBuffer. Most of the code looked like this:

    String thelist;
    thelist = "<select name=\"journal\">\n";
    thelist = thelist + "<option value=\"0\" selected >- no journal-</option>\n";
    while (result.next()){
    	thelist = thelist + "<option value=\"" + result.getInt("JournalID") + "\"" + myselect + ">" + result.getString("JournalTitle") + "</option>\n";
    }
    thelist = thelist + "</select>\n";
    

    The client once complained of a page loading too slowly. I put in some timers and found that one of the functions was taking 30 seconds to run. One function, that generated an html select statement, took 30 seconds to run. I switched it to using a StringBuffer and the function took .03 seconds to run (IIRC). This was the technique used throughout the entire site. That includes hundreds of lines of bad table layout html embedded deep in a "class."

    Fortunately I got the chance the completely refactor the site a few months later.

  • Lothar (unregistered)

    I see HTML being generated. I'm sure this part of the code resides inside a Servlet.

    So the biggest WTF here is to create a String anyway and not write the stuff directly to the Writer of the ServletResponse (you buffer the result only if it's not sure if there will be a redirect as response and not the data).

    Regards, Lothar

  • Derrick Pallas (cs) in reply to MrBester
    MrBester:
    also: onClick isn't closed. Sometimes you just know this was aimed at IE...

    Oops, that's just me screwing up the editing.

    Lothar:
    So the biggest WTF here is to create a String anyway and not write the stuff directly to the Writer of the ServletResponse (you buffer the result only if it's not sure if there will be a redirect as response and not the data).

    Exactly. Someone "heard of an optimization" without understanding it and they used it inappropriately. Furthermore, they should have been returning a data-structure or writing to a response directly.

  • Skurry (unregistered)

    I think the real WTF here is that they didn't use a template engine like Velocity. Stitching an HTML page together in Java is real awkward.

  • Paolo Perrotta (unregistered)

    This has been idiomatic Java for many years, and in fact using a StringBuffer instead of plain old string concatenation has been suggested by many authors. Today's compilers don't need it anymore, but it's still widely used. The bad readability only goes to proof that Java is terrible at string manipulation. The author should have used a different solutions such as a template engine - but again, generating HTML from code is a common practice, if a bad idea.

    The argument about not using string concatenation within calls to append() doesn't hold. The difference between append() and the concatenation operator has always been minor for short strings. Again, concatenating small strings and then appending them to a long StringBuffer is common practice.

    Apart from that, there is no proof that the original author didn't actually profile this. It smells of premature optimization, but I can't be sure it is, in the context of this particular system.

  • Woody (unregistered) in reply to This is probably not a WTF at all.

    It might not be true anymore, but if this code was written at the time when Java 1.1 was still new & shiny, this is probably not at all a WTF

    I'm stuck running on a 1.1 system, and I think as soon as you hit 3-4 strings being concatenated you start to see the beneift of a StringBuffer over straight up concatenation (based solely on the number of concat operations and the number of temp objects). The system I run on is very sensitive to garbage collection, so I tend to focus more on fewer objects than anythign else.

    I've easily seen 10x performance increases by switching tons of concats over to stringbuffers. Even with shorter lengths of strings (like the appends inside each of thier sb.append() parameter lists).

    That same garbage collection issue is why I don't bother to create xml using objects to wrap the elements (too expensive in the garbage collector and object creation), but again, my poor box takes a second or two to produce a couple hundred bytes of compact xml (1-2 letter element and attribute names).

  • Darin (unregistered) in reply to Hit

    Not knowing Java that well, I don't see any problem here. Does the compiler not turn "foo1"+"foo2" into "foo1foo2" at compile time?

  • Homer J. (unregistered)
    Comment held for moderation.
  • Uri (unregistered)

    I'm not sure why everyone is ganging up on this one.

    Personally, this code looks to me like something that would produce debug traces or exception traces to an external file. Debug traces can be turned off in production anyway, whereas I don't usually worry about the performance in exception situation. The WTF may be why the code remained in this, but we don't even know that the function is called.

    The bigger problem is that the code is not too readable or maintainable... I personally use an XML writer class to make such code more readable, but I probably pay more for functioncalls.

    String optimization is important, of course, though it's more important when used inside loops or in critical code, rather than when the cost is constant. We don't know anything about the rest of the application to know if we should even care about it.

  • Leaf (unregistered)

    The BIG WTF for me is that in C# and Java the StringBuilder class doesn't override the + operator to make using the .Append method optional/obsolete. (because in my opinion .Append() makes code harder to read.

    I never understood why they didn't implement the + operator to append strings to StringBuilders. Some method like this in the StringBuilder class would help make code easier to read and makes sence to me.

    public static StringBuilder operator +(StringBuilder a, object b) { return a.Append(b); }

    Then you could write code like this

    StringBuilder sb = new StringBuilder(); sb += "Foo" + somevar + "Bar";

    and it would be the same as:

    sb.Append("Foo").Append(somevar).Append("Bar");

    I find the former is much easier to read.

    I'm probably guilty of writing code like this wtf, I don't consider it to be that much of an offence. I've always been interested in when you should use the stringbuilder and when just using the + operator for strings is ok.

    Doing some research a year or two ago, I found some test cases had determined that +'ing less than 4 strings/vars is faster than using a StringBuilder. and when concatenating more than that a StringBuilder's Append method is faster.

    which is why sometimes I combine the two.

    Definately use SB's in loops though.

  • Leaf (unregistered)

    The BIG WTF for me is that in C# and Java the StringBuilder class doesn't override the + operator to make using the .Append method optional/obsolete. (because in my opinion .Append() makes code harder to read.

    I never understood why they didn't implement the + operator to append strings to StringBuilders. Some method like this in the StringBuilder class would help make code easier to read and makes sence to me.

    public static StringBuilder operator +(StringBuilder a, object b) { return a.Append(b); }

    Then you could write code like this

    StringBuilder sb = new StringBuilder(); sb += "Foo" + somevar + "Bar";

    and it would be the same as:

    sb.Append("Foo").Append(somevar).Append("Bar");

    I find the former is much easier to read.

    I'm probably guilty of writing code like this wtf, I don't consider it to be that much of an offence. I've always been interested in when you should use the stringbuilder and when just using the + operator for strings is ok.

    Doing some research a year or two ago, I found some test cases had determined that +'ing less than 4 strings/vars is faster than using a StringBuilder. and when concatenating more than that a StringBuilder's Append method is faster.

    which is why sometimes I combine the two.

    Definately use SB's in loops though.

  • Leaf (unregistered)

    The BIG WTF for me is that in C# and Java the StringBuilder class doesn't override the + operator to make using the .Append method optional/obsolete. (because in my opinion .Append() makes code harder to read.

    I never understood why they didn't implement the + operator to append strings to StringBuilders. Some method like this in the StringBuilder class would help make code easier to read and makes sence to me.

    public static StringBuilder operator +(StringBuilder a, object b) { return a.Append(b); }

    Then you could write code like this

    StringBuilder sb = new StringBuilder(); sb += "Foo" + somevar + "Bar";

    and it would be the same as:

    sb.Append("Foo").Append(somevar).Append("Bar");

    I find the former is much easier to read.

    I'm probably guilty of writing code like this wtf, I don't consider it to be that much of an offence. I've always been interested in when you should use the stringbuilder and when just using the + operator for strings is ok.

    Doing some research a year or two ago, I found some test cases had determined that +'ing less than 4 strings/vars is faster than using a StringBuilder. and when concatenating more than that a StringBuilder's Append method is faster.

    which is why sometimes I combine the two.

    Definately use SB's in loops though.

  • PHP coder (unregistered)

    The REAL WTF is that people are using Java as a HTML pre processor.

    j/k Sorry, couldn't resist! :P

  • Murray Brandon (unregistered)

    Not a WTF really. Too often I see overzealous idiots trying to optimise first when their design sucks and their code is really poorly formatted /unmaintainable /unreadable /badly designed. If using StringBuffer vs String in those small instances really made a difference to your application succeeding or failing then you're screwed anyway. Fix the design first. Unless doing video game development, most of the time your CPU is sitting waiting for I/O or for a database query result to return, so there's more value spending time on maintainability. At least the person's related strings were near each other and clearly related. My preference would be to create an "addParam(sb,paramName,paramValue)" method that handled null values, but that's not essential. Optimise last.

    The comment someone made about splitting MVC layers didn't make sense either. It looks like the code is from some kind of HTML renderer (eg. JSF) - Java can be an appropriate place to do it especially when you need to inject IDs and complex data into the HTML.

    Did I mention Optimise last?

  • Anonymous (unregistered)

    The comments section of the site is badly broken in Safari and the home page in Firefox... :(

    Captcha: Alarm

  • Anonymous (unregistered) in reply to XIU
    XIU:
    Hit:
    Ralf Engels:
    Isn't it a little bit stupid to use "append" and then have String contatinations inside the parameters?

    Actually, the (Java/C#) compiler is smart enough to take all concatinations like this:

    "foo" + "foo2" + "foo3"...

    and turn them into

    StringBuffer _temp = new StringBuffer();

    _temp.append("foo").append("foo2").append("foo3")...

    and then return the String object from that.

    Which doesn't make this any less of a WTF, because once again we have idiotic "optimization" for a process that likely doesn't need it and will simply make for harder maintenance.

    The C# compiler will even take true string constants and just combine them so:

    string test = "foo1" + "foo2";

    will be compiled to

    string test = "foo1foo2";

    For up to 4 strings it will use string.Concat if you're using variables.

    The real WTF I see here is that most of the string literals could be combined. So the following code:

    sb.append("TYPE="" + TYPE + " " "); sb.append("CELL="" + CELL_TYPE + """ ");

    Should have been:

    sb.append("TYPE=""); sb.append(TYPE); sb.append(" " CELL=""); sb.append(CELL_TYPE); sb.append(""" ");

    Oh well, some people will never learn...

    The Java Language Spec defines the same behavior, and javac does turn constant string expresions into constants at compile time. That's why breaking a string into multiple lines and adding a + at the end of a line has no difference on performance. :)

  • Anonymous (unregistered) in reply to Leaf

    What you describe is exactly what the csc and javac (1.4+) compilers do when you use the + operator!

    The real performance issue for strings now is when using them in loops.

    Logically:

    str := new string
    loop 100 times as counter do
    str += counter
    end
    

    You're going to get 100 throw-away StringBuilder objects from that loop.

  • GN (unregistered) in reply to MrBester
    MrBester:
    also: onClick isn't closed. Sometimes you just know this was aimed at IE...

    captcha: onomatopoeia. WTF? Don't you know œ is a diphthong?

    <ot> Actually, it's a ligature </ot>

  • Jimmy Jones (unregistered) in reply to This is probably not a WTF at all.
    This is probably not a WTF at all.:
    Depending on exactly when this code was written, it might not be a WTF *at all*.

    I agree.

    If there was only one line of code it would be a de-optimization but there's several lines of .append() so it's probably a net gain in speed.

    Whether it's the right way to do it or whether or not it needed this optimization is debatable but down at the bytecode level I don't see a problem.

  • Joost (unregistered)

    The real WTF is using the printf pattern for creating HTML.

  • Nis L. Simonsen (unregistered) in reply to MrBester
    MrBester:
    also: onClick isn't closed. Sometimes you just know this was aimed at IE...

    captcha: onomatopoeia. WTF? Don't you know œ is a diphthong?

    So onclick isn't closed.. How exactly does this "aim" it at IE (in which it won't work anymore than it will in firefox / opera / whatever) ??

  • MrBester (unregistered) in reply to Nis L. Simonsen

    Ahh, the assumption that a particular sentence is a continuation of the previous one...

    As already stated (for sentence 1), it was an editing error. As for sentence 2: variable case attributes and whitespace between the attribute name and = are typical of the "can't be bothered as IE parses it anyway" approach to HTML

    Captcha: ninjas. Ultimate Ninja Power!

  • cthulhu (unregistered)

    Generating HTML in code like that is just wrong. Load it from file or something.

  • James (unregistered) in reply to Joost
    Joost:
    The real WTF is using the printf pattern for creating HTML.
    You mean, the real WTF is using the printf pattern for creating HTML in Java.

    :P

  • Zylon (unregistered)

    The real WTF is people who casually drop "pattern" references in an attempt to sound like supar smarty programmer man.

  • Jack Moxley (unregistered)

    Why why why use StringBuffers, most of your examples in the comments show a StringBuffer being used by one thread within a method, I see absolutly no need for the overhead causd by using a synchronized implementation of the much faster StringBuilder!

Leave a comment on “String Optimizations in Java”

Log In or post as a guest

Replying to comment #:

« Return to Article