• Post Reply Bookmark Topic Watch Topic
  • New Topic

StringBuffer reintialization

 
Himanshu Khanna
Greenhorn
Posts: 29
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi All ,
I am using StringBuffer for building a row to be written to a file . After writing one row to the file I need empty the StringBuffer object so as to use it again.
I am using strBuf = new StringBuffer() to do this .
Another way possible is delete method of StringBuffer (I think but haven't used ever)
Please advice which way is better keeping issues of performance & memory in mind.
Thanks
 
Bill Krieger
Ranch Hand
Posts: 53
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Himanshu Khanna:
Hi All ,
I am using StringBuffer for building a row to be written to a file . After writing one row to the file I need empty the StringBuffer object so as to use it again.
I am using strBuf = new StringBuffer() to do this .
Another way possible is delete method of StringBuffer (I think but haven't used ever)
Please advice which way is better keeping issues of performance & memory in mind.
Thanks

Creating an entire new Stringbuffer object has to be inefficient. How about just invoking strBuf.setLength(0). That would improve performance. It also wouldn't leave a bunch of StringBuffer objects floating in memory waiting to be GC'd the way your "strBuf = new StringBuffer()" does.
Bill
 
Himanshu Khanna
Greenhorn
Posts: 29
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the suggestion Bill !!
It wud be much better indeed to use setLength() rather than reintializing ..
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This technique is not as effective as you might think - in fact, it can even make things worse. Internally, a StringBuffer has an array of chars representing its contents. Allocating (and reallocating) memory for this buffer is often the main expense in using a StringBuffer. The String class also uses a char array internally - and when you call toString() on a StringBuffer, it actually saves itself some time by passing the existing char array to the new String as its underlying representation. Which is a good way to speed things up for you - except that if you subsequently modify the StringBuffer, the StringBuffer can't allow you to modify that same array again, since it's now the basis of a String, which is supposed to be immutable. So instead it makes a copy of the array and uses the copy as the new internal representation of the StringBuffer contents - leaving the old array exclusively to the String. Thus, when you re-use the StringBuffer, you will still be creating at least one new char array each time you modify the contents after a toString() call.
In fact, this will probably be less efficient than creating a new buffer, as you can't control the capacity of the new buffer very well at all. It will start out at the same capacity as the old buffer, and will never decrease. So if you once created a 10,000-char String with this StringBuffer, every time you subsequently reuse it you will have to create a new char[10000] (or whatever the actual capacity was - probably somewhere between 10,000 and 20,000). Even if you're only planning on 20 characters this time. Much more efficient to start with a fresh StringBuffer in this case.
 
Himanshu Khanna
Greenhorn
Posts: 29
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Jim for the valuable input ..I was about to change the implementation in my code i.e. moving from new to setLength() ..
Thanks again..
 
Doco Todd
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't think that's true...
String objects are made immutable by keeping their internal char array "out of reach". So a result of toString() on a StringBuffer will NOT result in those two object sharing the same char array; instead the new String object creates a new array and copies the content from that of StringBuffer object. The StringBuffer may be subsequently used, and called setLength() without any fear that it's array will be recreated.
 
Peter den Haan
author
Ranch Hand
Posts: 3252
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Doco Todd:
I don't think that's true...
Don't think, but know. Especially when contradicting Jim . The source for the Java libraries is available for download; if you browse it, you'll see in StringBuffer:The code in String reads:The StringBuffer is marked as "shared" and the String is backed by the buffer's char array. StringBuffer methods that actually modify the array will make a copy if it has been marked as shared, so that the String is immutable, e.g.:So, Jim is right.
Of course
- Peter
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It's amazing the things one can learn by reading the source code provided by Sun. I was looking at the code for SDK 1.3.1; it's possible that other versions implement this differently.
 
Doco Todd
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Sorry about the other post, I was mistaken.
I did browse some sources of some "adapted" (no syncronizations) StringBuffer class. I assumed that the author did not modified toString() method, which was:

Apparently, he did.
Also, it seemed naturally to me for String object to simply copy the needed array and let the StringBuffer alone.
Did this post made me look less stupid? I think not. I will think (and check) again before contradicting another sheriff.
 
Himanshu Khanna
Greenhorn
Posts: 29
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hey All ,
Wow ..I say thats the best way of learning
seeking the advice of Best Minds & Experienced Hands ..
Thanks for such an extensive response ...
 
rahulk kumar
Greenhorn
Posts: 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
[I have been using a sb.delete(0, sb.length())
How's that for performance ?
Thanks.
------------------
 
Peter den Haan
author
Ranch Hand
Posts: 3252
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have been using a sb.delete(0, sb.length()) How's that for performance ?
So have I - in another thread - I'm not sure what I was thinking. Anyway, it's okay; it makes an unnecessary call to System.arraycopy() to move a 0 byte array, that shouldn't waste an inordinate amount of time. But use setLength() by all means.
- Peter
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!