Am 26.02.2013 12:53, schrieb Roedy Green:
So I googled and found a FastCat class that has append(String ...) and
append(Object ...) methods. And just by coincidence, you're a co-author
of that class.
Shocking, Roedy advertising for himself.
So, are you aware of the performance hit? Are you trying to say, that
you prefer convenience over performance here? And if you don't care
about performance in this particular case, why don't you use the +
operator for Strings which is pretty convenient? Or why don't you
exploit the fact that append() returns the StringBuilder instance?
I'm not sure, what to make of your posting. Are you just trying to
promote the FastCat class?
Would you happen to have a benchmark, where you append lots of integers
to a FastCat and a StringBuilder? I would love to see what happens if
you use the append(Object...) method for that.
Because his incessant advertising irritates me, I spent a few minutes
writing a small benchmark, comparing the performance of StringBuilder,
StringBuffer and FastCat. The results were ... well, pretty much what one
would expect:
Took 00:08.845ms to append 454,895,082 chars total with FastCat.
Took 00:03.939ms to append 454,895,082 chars total with StringBuffer.
Took 00:03.462ms to append 454,895,082 chars total with StringBuilder.
So FastCat is about 2.3 times slower than the Oracle/Sun implementation of
StringBuffer, and 2.6 times slower than the unsychronized StringBuilder.
Shocker.
Not wanting to be too harsh on Roedy, seeing as how he's probably freed
Europe during WWII, I figured I'd run the benchmark again, but instead of
instantiating millions of StringB*S/FastCatS, I'd reuse the same one.
Maybe, after all, it was the object creation that caused the difference.
Hilariously, at this point, I started getting exceptions thrown into my
face - FastCat doesn't support fancy things like appending more than 1000
chars or so. And instead of signalling that with a proper error code, it
abuses ArrayIndexOutOfBoundsException to signal that it ... refuses to
resize itself ?
Don't get me wrong, it's not a bug causing that, he actually explicitly
throws that exception when his buffer gets full, outright refusing to
resize the object. Because terminating with an exception is better for
performance ... right ?
/**
* We overflowed the array. Give up. Get user to improve estimate. We
could recover automatically,
* but that would defeat the intent of fast code.
*/
Couldn't make this up if I tried. I decided to FastCat's metaphorical arm
over my shoulder and just told it to make more buffer space in the
constructor, and this is the glorious outcome of reusing the same SB/FC
object:
Took 00:14.763ms to append 454,895,082 chars total with FastCat.
Took 00:03.384ms to append 454,895,082 chars total with StringBuffer.
Took 00:02.825ms to append 454,895,082 chars total with StringBuilder.
At this point, I vote that Roedy has to rename it to SlowCat.
Test code (ugly, but too lazy to clean it up):
<
http://pastebin.com/TNj7Fmqy>
Note that you need plenty of RAM if you want to keep all those bytes in
memory. I used -Xmx4G -Xms4G, though you can probably make due with less.
ps.: When I just went to post the code, I noticed that by accident I didn't
actually *USE* Roedys advanced syntax. Instead, as with the SB classes, I
used multiple .append()s. Talk about embarassing, luckily I noticed before
I pressed send.
I was about ready to delete this whole post, thanking the good spirits of
Usenet for saving me from the shame of publically embarassing myself when
it turned out that a small change to his advanced syntax would speed
FastCat up by leaps and bounds.
No. In fact, his advanced syntax is *EVEN* *SLOWER*: 6.4 times slower than
StringBuilder, to be exact.
Took 00:18.016ms to append 454,895,082 chars total with FastCat.
Liebe Gruesse,
Joerg