Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4511930

Inefficiency in StringBuffer class

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Duplicate
    • Icon: P4 P4
    • None
    • 1.4.0
    • core-libs
    • generic
    • generic



      Name: ddT132432 Date: 10/08/2001


      java version "1.4.0-beta2"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta2-b77)
      Java HotSpot(TM) Client VM (build 1.4.0-beta2-b77, mixed mode)


      StringBuffer.toString() shares the character array with String,
      so that one can efficiently build up a string in the buffer and take
      the resulting String without copying.

      If the StringBuffer is subsequently modified, it makes a copy of the character
      array, and there is a common use of StringBuffer that leads to very inefficient
      use of memory. Say one is parsing into a StringBuffer, emitting
      String's, then zeroing the StringBuffer with setLength(0) for the next String.
      These emitted strings are of length of the maximum length the StringBuffer
      has reached to that point! If there has been a 200 character token, then
      all future toString()'s make 200 character String's, even if they are just
      a few characters long.

      This problem has been stated as JavaOne and one can see this from the source
      code, but it is very non-obvious, even surprising, and obviously
      potentially hugely wasteful.

      It should be easier to do the right thing. Perhaps it would be enough to
      document this inefficient usage in the methods involved -- toString() and
      setLength() -- with the suggestion to use StringBuffer.substring(0), which does
      exactly what one might think toString() does. HotSpot has very efficient
      memory allocation, so perhaps in some cases it would be efficient to create a
      new StringBuffer for each new String at the same place as setLength(0),
      but in some cases it's not clear what initial size should be, a size which
      would have been established from previous parsing with the setLength(0)
      approach, so making new StringBuffers either makes them too large or suffers
      copying costs during expansion. (Having setLength(0) turn off the shared
      flag works too late: the toString() String has already been created with
      the overlong length.) Still, both options are implementation dependent,
      and the knowledge not well advertised. Perhaps it would be better
      to explictly define a function that does the right thing:

      /**
          Return the current contents of the buffer,
          and clear the buffer for subsequent reuse.
          Should be used instead of toString() / setLength(0).
      */
      public String reset() {
        String str = substring(0);
        setLength(0);
        return str;
      }
      (Review ID: 133281)
      ======================================================================

            mmcclosksunw Michael Mccloskey (Inactive)
            ddressersunw Daniel Dresser (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: