aspose file tools*
The moose likes Java in General and the fly likes String and StringBuffer Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Soft Skills this week in the Jobs Discussion forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "String and StringBuffer" Watch "String and StringBuffer" New topic
Author

String and StringBuffer

Derek Baker
Ranch Hand

Joined: May 23, 2003
Posts: 46
I realize there is some benefit to constructing long Strings by using a StringBuffer object and then calling toString(), rather than repeatedly concatenating String objects.

I'm wondering though, if there is some rule about how many Strings are being concatenated that makes it easier to decide if I should use the StringBuffer method. If I'm just concatenating two strings, is it still beneficial to go through a StringBuffer first? If not two, then what is the limit? And does the number of characters have anything to do with it?

Derek
Bruce Jin
Ranch Hand

Joined: Sep 20, 2001
Posts: 671
I don't think it matters that much if only a few or a few douzen strings are involved.
However your application may be accessed by many users at the same time(like a servlet), then it may matter a little bit.
You can set up a loop (10,000,000 times for example) to test this.


BJ - SCJP and SCWCD
We love Java programming. It is contagious, very cool, and lot of fun. - Peter Coad, Java Design

Crazy Bikes created by m-Power
Dave Wood
bronco
Ranch Hand

Joined: Aug 02, 2004
Posts: 161
I believe there really is no lower limit. As soon as you do the first concat, the JVM creates a StringBuffer behind the scenes anyway...so even with just two, you might as well create it yourself since it's going to happen anyway.


Co-Author of <a href="http://www.oreilly.com/catalog/jswing2" target="_blank" rel="nofollow">Java Swing</a><br />Co-Creator of <a href="http://www.sun.com/training/catalog/courses/CX-310-055.xml" target="_blank" rel="nofollow">SCJP 5.0</a> and <a href="http://www.sun.com/training/certification/java/associate_beta.xml" target="_blank" rel="nofollow">SCJA</a> exams
Julian Kennedy
Ranch Hand

Joined: Aug 02, 2004
Posts: 823
IMO it's a trade-off between performance (and maybe memory efficiency) and convenience/clarity. If the part of your app doesn't require high performance do it which ever way is clearest/most convenient. If it does, use StringBuffer().
David Harkness
Ranch Hand

Joined: Aug 07, 2003
Posts: 1646
Originally posted by Julian Kennedy:
IMO it's a trade-off between performance (and maybe memory efficiency) and convenience/clarity. If the part of your app doesn't require high performance do it which ever way is clearest/most convenient. If it does, use StringBuffer().

Good advice. As noted any String concatenation is turned into StringBuffer appendage by the compiler. I've seen timing tests showing that letting the compiler do the work turned out to be slightly faster.

However, if you're tuning for performance by using a StringBuffer, make sure you create it large enough to hold the entire concatenated String to avoid having to resize (create, copy, destroy) the buffer multiple times. In Java 1.3 and 1.4, the buffer starts at 16 characters by default and doubles* in capacity during a resize (unless more space is needed).

For example, if you concatenate a bunch of smallish Strings that come out to 500 characters, StringBuffer will create 6 buffers with lengths 16, 34, 70, 142, 286, and 574. It will also need to copy the contents from one to the next along the way. You can avoid all of that by using StringBuffer(600) or some value that you think will be enough.

* Instead of merely doubling, expandCapacity(int minimumCapacity) adds one to the current capacity and doubles the result. If this is smaller than minimumCapacity, it will use minimumCapacity instead.
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
Originally posted by David Harkness:
Good advice. As noted any String concatenation is turned into StringBuffer appendage by the compiler. I've seen timing tests showing that letting the compiler do the work turned out to be slightly faster.
Do you have a reference for that? The bytecode for compiler-generated string concatenation looks to be identical to the code you'd get if you'd do it explicitly, but I might have missed something.

However, if you're tuning for performance by using a StringBuffer, make sure you create it large enough to hold the entire concatenated String to avoid having to resize [...] the buffer multiple times. [...] You can avoid all of that by using [...] some value that you think will be enough.
Are you sure you want to advise this? Because, as so often in attempts at Java string optimisation, there are subtle traps for the unwary. The trap in this case is that the char[] array that backs the StringBuffer is also going to back any String that you derive from the buffer. Someone reading your explanation might think "right, I'll just make sure my StringBuffer is always large enough" and find in the end that all his little Strings take up WAY more memory than they ought to.

Of course, when you know beforehand what size the buffer is going to grow to it's worth presizing it, but if you don't know exactly what the size is going to be then it's usually best to stay well clear.

- Peter
David Harkness
Ranch Hand

Joined: Aug 07, 2003
Posts: 1646
Originally posted by Peter den Haan:
Do you have a reference for that?
I couldn't find the original article (it was at least a year ago, probably two), but the difference 1) was extremely marginal in favor of + and 2) only applied to single-statement concatenation.
I did, however, find some interesting related pages. Of course, there is no overall agreement, and everyone pretty much says "Always/Never use String/StringBuffer," so take your pick.
  • http://www.javaspecialists.co.za/archive/Issue068.html
  • http://java.sun.com/developer/JDCTechTips/2002/tt0305.html#tip1
  • http://c2.com/cgi/wiki?StringBuffer
  • http://www.precisejava.com/javaperf/j2se/StringAndStringBuffer.htm
  • http://wiki.java.net/bin/view/Javapedia/AlwaysUseStringBufferMisconception
  • http://www.coderanch.com/t/201827/Performance/java/StringBuffer-not-outperforming

  • Are you sure you want to advise this?

    As with all advice, if you follow it blindly, bad things are likely to happen. I guess my first advice would be to make sure you need to optimize this in the first place. This is what we've all been saying, but it's worth saying again.

    I would recommend checking out the StringBuffer source for those that are really curious. One of the links above mentioned that for JDK 1.4.1 SB was changed such that clearing it -- setLength(0) -- now makes a copy of the char[] buffer even though the old version of the JDK optimized this away. If you're clearing the buffer, certainly you don't need a copy of it to modify. Thus, in general, do not reuse StringBuffers once you've called toString() on them, pegging a String to its underlying buffer.
    Joyce Lee
    Ranch Hand

    Joined: Jul 11, 2003
    Posts: 1392
    Seeking for your opinions. The following code was extracted from http://java.sun.com/developer/JDCTechTips/2002/tt0305.html#tip1. I'm not asking for performance issue since StringBuffer is definitely better than String in this case. What I'm asking is which approach is more readable in this example. Which approach do you prefer and why?



    Joyce
    Petr Blahos
    Ranch Hand

    Joined: Apr 28, 2004
    Posts: 131
    Originally posted by Joyce Lee:
    What I'm asking is which approach is more readable in this example. Which approach do you prefer and why?


    Hi Joyce,

    I believe that as to the readability those 2 approaches are
    totaly equal because the examples are really short. I think
    this readability issue is more visible in examples like:



    which would sprawl over 7 lines when using sb.append.

    But I must explicitly mention that I do not advocate using Strings.
    For the above examples use of StringBuffer and append is a must.

    Petr


    Get a better web browser:<br /><a href="http://www.mozilla.org/products/firefox/switch.html" target="_blank" rel="nofollow">http://www.mozilla.org/products/firefox/switch.html</a>
    Joyce Lee
    Ranch Hand

    Joined: Jul 11, 2003
    Posts: 1392
    Thanks Petr. I purposely used this example to seek for opinion. I've the same sentiment as you, both are equally the same in term of readability in above example. But still, some would still prefer one approach over the other and I would like to know why. For example, String approach may be preferable because StringBuffer has more lines. Or maybe, performance issue shouldn't take into consideration while coding.

    I read the book "Better, Faster, Lighter Java" by Bruce A. Tate and Justin Gehtland. In this book, it advocates simplicity which I wholeheartedly agree. On page 25, it compares the readability between String and StringBuffer using the following example:


    The author prefers String approach as it has lesser code. His advice: Trade a little less performance for better readability every time.

    But what if I change the StringBuffer code to:

    Neater. In term of readability, both look the same to me. In term of performance, can't notice the difference. In term of code size, StringBuffer has two more lines than the String approach. For in this case, I'd go for String approach.

    Any comments?

    Joyce
    Peter den Haan
    author
    Ranch Hand

    Joined: Apr 20, 2000
    Posts: 3252
    Originally posted by Petr Blahos:
    I think this readability issue is more visible in examples like:which would sprawl over 7 lines when using sb.append.
    But would it?I feel this is clearer, if only because the way I broke it up keeps the HTML tags together.

    Some have religious objections to method chaining, but I think it's great in cases like this. Ditto for, say, Hibernate Criteria or a Spring ModelAndView and a couple of other APIs where this style is supported because it's a really convenient way to make lots of little method calls on the same object.

    - Peter
    [ September 01, 2004: Message edited by: Peter den Haan ]
    Stefan Wagner
    Ranch Hand

    Joined: Jun 02, 2003
    Posts: 1923

    For readability, I would prefer the += operator:

    If such code is called often inside a loop or might be called often: sb.append!
    What is often?

    But perhaps:


    is just better readable?
    Not really.
    And performance shouldn't be very good.

    [ September 01, 2004: Message edited by: Stefan Wagner ]
    [ September 01, 2004: Message edited by: Stefan Wagner ]

    http://home.arcor.de/hirnstrom/bewerbung
    Julian Kennedy
    Ranch Hand

    Joined: Aug 02, 2004
    Posts: 823
    I realise these are examples guys but there's really no need to write HTML in Strings now that we have JSP, right? We don't want to go back to the mess that I've seen in pre-JSP servlet apps. It still surprises me that no one thought to use HTML templates.

    Jules
    Petr Blahos
    Ranch Hand

    Joined: Apr 28, 2004
    Posts: 131
    Hi Julian,

    Well, to be honest, I really don't feel like including
    a jsp engine in my small standalone swing application ;-)
    (Yes, that's where I use HTML).

    But thanks for your idea about templates. A quick thought
    tells me that it is probably going to be slower than
    appends but I might give it a try.

    Petr
    Peter den Haan
    author
    Ranch Hand

    Joined: Apr 20, 2000
    Posts: 3252
    Originally posted by Petr Blahos:
    But thanks for your idea about templates. A quick thought tells me that it is probably going to be slower than appends but I might give it a try.
    It is slower, but that might not at all be important. Can I suggest you look at Velocity?

    - Peter
     
    I agree. Here's the link: http://aspose.com/file-tools
     
    subject: String and StringBuffer