StringBuilder's performance lower than that of StringBuffer
Hi,
I read in many websites than StringBuilder offers better performance than StringBuffer. So, in my code, I changed all StringBuffer usages to StringBuilder. But now the performance has worsened. Is it that StringBuffer is really more performant? Also, is there any better performant way than using StringBuilder & StringBuffer?
Thanks.
[361 byte] By [
GSPa] at [2007-10-3 3:28:04]

StringBuilder is not synchronized, thus usually quicker. What are you doing? What's your code? How did you test?
Hi,Mainly, the code uses StringBuffer's append method to append characters to it. This append method seems to take nearly 60% of CPU time!Thanks
GSPa at 2007-7-14 21:21:35 >

> Mainly, the code uses StringBuffer's append method to> append characters to it. This append method seems to> take nearly 60% of CPU time!Doesn't mean anything. Please post your code and tell us how you measured the performance.
Hi,
There are 100s of snippets of code here & there in the application which use StringBuilder's appen(). Pasting few here:
1.
s = new StringBuffer((s + "").substring(0,(s + "").indexOf("</QUERY>")));
s.append(finalMapString);
s.append("</QUERY>");
2.
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append(rootDirectory).append(File.separator).append(visitorResult.getRSQID()).append(visitorResult.getSequence()).append(".").append(visitorResult.getDataFileType());
3.
private StringBuffer output = new StringBuffer();
output.append("<" + tagName) ;
In all the above code, I had simply replaced StringBuffer with StringBuilder & measured performance i.e. CPU time usage using profiler.
Thanks.
GSPa at 2007-7-14 21:21:35 >

Example #2 test:
import java.io.*;
class TestRunner {
static final int TEST_RUNS = 10;
public static void main(String[] args) throws Exception {
VisitorResult result = new VisitorResult();
String rootDirectory = "root";
Test[] tests = {
new StringBufTest(rootDirectory, result),
new StringBldTest(rootDirectory, result)
};
for (int i = 0; i < TEST_RUNS; i++) {
for (Test t : tests) {
t.execute();
clean();
}
System.out.println("\n \n");
}
}
static void clean() {
for (int i = 0; i < 3; i++) System.gc();
System.runFinalization();
try { Thread.sleep(100); } catch (Exception e) { }
}
}
interface Test {
void execute() throws Exception ;
}
abstract class AbstractTest implements Test {
static final int ITERATIONS = 100000;
abstract void doTest() throws Exception;
public void execute() throws Exception {
long start = System.currentTimeMillis();
for (int i = 0; i < ITERATIONS; i++) {
doTest();
}
long finish = System.currentTimeMillis();
long elapsed = finish - start;
printResults(elapsed);
}
private void printResults(long elapsed) {
System.out.printf("%s (%d iterations) -> total elapsed: %6d millis, average: %.6f millis\n",
getClass().getName(), ITERATIONS, elapsed, (double) elapsed / ITERATIONS);
}
}
class StringBufTest extends AbstractTest {
private String rootDirectory;
private VisitorResult visitorResult;
StringBufTest(String rootDirectory, VisitorResult result) {
this.rootDirectory = rootDirectory;
this.visitorResult = result;
}
void doTest() throws Exception {
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append(rootDirectory)
.append(File.separator)
.append(visitorResult.getRSQID())
.append(visitorResult.getSequence())
.append(".")
.append(visitorResult.getDataFileType());
}
}
class StringBldTest extends AbstractTest {
private String rootDirectory;
private VisitorResult visitorResult;
StringBldTest(String rootDirectory, VisitorResult result) {
this.rootDirectory = rootDirectory;
this.visitorResult = result;
}
void doTest() throws Exception {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(rootDirectory)
.append(File.separator)
.append(visitorResult.getRSQID())
.append(visitorResult.getSequence())
.append(".")
.append(visitorResult.getDataFileType());
}
}
class VisitorResult {
String getRSQID() { return "rsqid"; }
String getSequence() { return "sequence"; }
String getDataFileType() { return "datafiletype"; }
}
Results:
StringBufTest (100000 iterations) -> total elapsed:62 millis, average: 0.000620 millis
StringBldTest (100000 iterations) -> total elapsed:63 millis, average: 0.000630 millis
StringBufTest (100000 iterations) -> total elapsed:78 millis, average: 0.000780 millis
StringBldTest (100000 iterations) -> total elapsed:47 millis, average: 0.000470 millis
StringBufTest (100000 iterations) -> total elapsed:109 millis, average: 0.001090 millis
StringBldTest (100000 iterations) -> total elapsed:78 millis, average: 0.000780 millis
StringBufTest (100000 iterations) -> total elapsed:94 millis, average: 0.000940 millis
StringBldTest (100000 iterations) -> total elapsed:46 millis, average: 0.000460 millis
StringBufTest (100000 iterations) -> total elapsed:62 millis, average: 0.000620 millis
StringBldTest (100000 iterations) -> total elapsed:47 millis, average: 0.000470 millis
StringBufTest (100000 iterations) -> total elapsed:79 millis, average: 0.000790 millis
StringBldTest (100000 iterations) -> total elapsed:47 millis, average: 0.000470 millis
StringBufTest (100000 iterations) -> total elapsed:78 millis, average: 0.000780 millis
StringBldTest (100000 iterations) -> total elapsed:47 millis, average: 0.000470 millis
StringBufTest (100000 iterations) -> total elapsed:62 millis, average: 0.000620 millis
StringBldTest (100000 iterations) -> total elapsed:62 millis, average: 0.000620 millis
StringBufTest (100000 iterations) -> total elapsed:62 millis, average: 0.000620 millis
StringBldTest (100000 iterations) -> total elapsed:47 millis, average: 0.000470 millis
StringBufTest (100000 iterations) -> total elapsed:63 millis, average: 0.000630 millis
StringBldTest (100000 iterations) -> total elapsed:47 millis, average: 0.000470 millis
This is all insignificant. How much execution time do you think you're going to save with this exercise? Personally I would be using new File(path,name) for most of what your test code does.
ejpa at 2007-7-14 21:21:36 >

> This is all insignificant. How much execution time do
> you think you're going to save with this exercise?
Is this directed at me? If so, I'm not hoping to save any execution time with this exercise. I was just taking a break this afternoon. I posted the results of the tests to show that the difference between using StringBuffer and StringBuilder at the level of the OP's demonstration is pretty much irrelevant in any practical sense.
> Personally I would be using new File(path,name) for
> most of what your test code does.
Personally, I would too (well, probably just "new File(path)"). But I wanted to run the test using as similar code as could get to the examples the OP used as demonstrations of what was causing so much trouble.
~
> Is this directed at me?No, at the OP of course. We are in agreement.
ejpa at 2007-7-14 21:21:36 >

> > Is this directed at me?> > No, at the OP of course. We are in agreement.Okay; thanks for clarifying. I was confused (obviously). :o)~
U have messed u with String ,String Builder, and StringBuffer
StringBuffer is better than String as StringBuffer object holds 16 bits of extra memory than actually it requires for the first time.
When u append more characters to StringBuffer object memory is always available hence no need to reallocte it ,which is the case for String.
> StringBuffer is better than String as StringBuffer
No, it's just different. They serve different purposes.
> object holds 16 bits of extra memory than actually it
> requires for the first time.
I haven't looked, but I highly doubt this is the case.
> When u append more characters to StringBuffer object
> memory is always available
> hence no need to reallocte
No. There may be extra space initially, but if you append enough, you'll use that up and have to allocate more.
> it ,which is the case for String.
That's not the whole picture. String is immutable. You can't change a String's contents after creation. It's not just a matter of allocating more memory. (You'll have to do that, but it will be in a completely new String object.)
jverda at 2007-7-14 21:21:36 >

> StringBuffer is better than String as StringBuffer
No, it's just different. They serve different purposes.
> object holds 16 bits of extra memory than actually it
> requires for the first time.
I haven't looked, but I highly doubt this is the case.
===u can reffer 'complete reference'
also u cancheck StringBuffer constructor which allows u to explicity specify buffer size
> When u append more characters to StringBuffer object
> memory is always available
> hence no need to reallocte
No. There may be extra space initially, but if you append enough, you'll use that up and have to allocate more.
===
if u try to append anything less than 16 char its works fine
but if u exceed it(say 25)
new space of(25-16)+16 will be allocated.
> it ,which is the case for String.
That's not the whole picture. String is immutable. You can't change a String's contents after creation. It's not just a matter of allocating more memory. (You'll have to do that, but it will be in a completely new String object.)
String function internally carrys out the same operation of string buffer whenever its contents are altered but doesn't hold any more space as its doesn't support append func directly.
> > object holds 16 bits of extra memory than actually
> it
> > requires for the first time.
>
> I haven't looked, but I highly doubt this is the
> case.
> ===u can reffer 'complete reference'
> also u cancheck StringBuffer constructor which allows
> u to explicity specify buffer size
The above makes no sense. Try to write more clearly. Whatever you're trying to say, though, it seems very different from "holds 16 bits of extra memory than actually it requires for the first time."
>
> > When u append more characters to StringBuffer
> object
> > memory is always available
> > hence no need to reallocte
>
> No. There may be extra space initially, but if you
> append enough, you'll use that up and have to
> allocate more.
> ===
> if u try to append anything less than 16 char its
> works fine
> but if u exceed it(say 25)
> new space of(25-16)+16 will be allocated.
Yes. But:
* You said 16 bits. Maybe you meant 17 bytes?
* You said "memory is always available, hence no need to reallocate it." But, as I said, if you use up more than what's initially available, the StringBuffer will have to allocate more. Perhaps you meant that you don't have to create a new object like you do with String. This is true, but it's because String is immutable.
> > it ,which is the case for String.
>
> That's not the whole picture. String is immutable.
> You can't change a String's contents after creation.
> It's not just a matter of allocating more memory.
> (You'll have to do that, but it will be in a
> completely new String object.)
>
> String function internally carrys out the same
> operation of string buffer whenever its contents are
> altered but doesn't hold any more space as its
> doesn't support append func directly.
No. String is immutable. You cannot change its contents after creation. That is the key difference betwen String and StringBuffer/Builder.
jverda at 2007-7-14 21:21:36 >

is string really mutuable
try out
String s="Good";
System.out.println(s);
s="Best";
System.out.println(s);
see if u get any complier errors,run time and so on
Back to StringBuffer
1. StringBuffer sb=new StringBuffer("hi");
System.out.println(sb +" Length"+sb.length());
sb.append(" Friend");
System.out.println(sb +" Length"+sb.length());
sb.append(" its going to be a great day ,isn't it");
System.out.println(sb +" Length"+sb.length());
try out men
> is string really mutuable
No.
> try out
>
> String s="Good";
> System.out.println(s);
> s="Best";
> System.out.println(s);
So where did any String change here? You just reassigned the reference to a new object.
[ _ ] You know what a reference is.
[ _ ] You know that the assignment operator does assignments
[ X ] You should study the basics again
> is string really mutuable
No. As I stated, it is immutable.
> try out
>
> String s="Good";
> System.out.println(s);
> s="Best";
> System.out.println(s);
You're not changing the contents of a String object. You're just pointing the reference variable at a different String object.
As I said, String is immutable: You cannot change the contents of a String object.
> Back to StringBuffer
Irrelevant.
jverda at 2007-7-21 10:11:21 >

vipulucky:final StringBuffer sb = new StringBuffer();So StringBuffer is suddenly immutable? I don't think so.