Re: String Buffer

K

kld

The information that you request is not important, since the main utility of
"Stringbuffer" is to avoid the operation "string += string", this is bad
when strings are long, independently of language or compiler.

Thanks.
 
J

John Harrison

kld said:
The information that you request is not important, since the main utility of
"Stringbuffer" is to avoid the operation "string += string", this is bad
when strings are long, independently of language or compiler.

Thanks.

string += string in C++ does exactly what StringBuffer does in Java.

john
 
T

tom_usenet

The information that you request is not important, since the main utility of
"Stringbuffer" is to avoid the operation "string += string", this is bad
when strings are long, independently of language or compiler.

How is StringBuffer.append(String) different to string += string?

There were some std::string implementations that don't grow their
capacity exponentially, but this isn't true of any recent
implementations. The algorithm used by StringBuffer.append is
identical used by that of modern std::string::append implementations.
You try to fit the other string into the available memory, and if you
can't, you reallocate your buffer to some factor multiplied by your
previous capacity.

Tom
 
T

tom_usenet

Actaully I possibly don't know what I'm talking about here, too hasty.

I just looked at a StringBuffer implementation, and it uses the exact
same algorithm as most string+= implementations (e.g. a contiguous
buffer with a separate size and capacity).

Tom
 
J

Johan Nilsson

kld said:
I totally disagree.

Test: JAVA: 27.5 seconds -- C++: 282.3 seconds

JAVA: 27.5 seconds
public static String fu()
{
StringBuffer sTmp = new StringBuffer(1000000);
for ( int i = 0; i < 1000000; i++ )
sTmp.append('0');
return sTmp.toString();
}

C++: 282.3 seconds
string fu()
{
string sTmp;

Did you try changing this to "string sTmp(1000000, ' ');" to make the
comparison a bit fairer ??

// Johan
 
R

Robert Bauck Hamar

* Johan Nilsson:
|
| |> I totally disagree.
|>
|> Test: JAVA: 27.5 seconds -- C++: 282.3 seconds
|>
|> JAVA: 27.5 seconds
|> public static String fu()
|> {
|> StringBuffer sTmp = new StringBuffer(1000000);
|> for ( int i = 0; i < 1000000; i++ )
|> sTmp.append('0');
|> return sTmp.toString();
|> }
|>
|> C++: 282.3 seconds
|> string fu()
|> {
|> string sTmp;
|
| Did you try changing this to "string sTmp(1000000, ' ');" to make the
| comparison a bit fairer ??

Or perhaps call sTmp.reserve(1000000)? I don't know how kld got his
numbers; I've got:
* java 1.4.1_02: 0.416 seconds
* g++ 3.2.3: 0.120 seconds (kld's code)
 
?

=?iso-8859-1?Q?Andr=E9_P=F6nitz?=

kld said:
I totally disagree.

JAVA: 27.5 seconds
StringBuffer sTmp = new StringBuffer(1000000);
C++: 282.3 seconds
string sTmp;

You are cheating. In the Java version you allocate a buffer of suitable
size whereas in C++ you don't. Try 'reserve' and post the results.

Andre'
 
T

tom_usenet

I totally disagree.

Test: JAVA: 27.5 seconds -- C++: 282.3 seconds

JAVA: 27.5 seconds
public static String fu()
{
StringBuffer sTmp = new StringBuffer(1000000);
for ( int i = 0; i < 1000000; i++ )
sTmp.append('0');
return sTmp.toString();
}

C++: 282.3 seconds
string fu()
{
string sTmp;
for ( int i = 0; i < 1000000; i++ )
sTmp += '0';
return sTmp;
}

Try this too:

vector<char> fu()
{
vector<char> tmp;
for ( int i = 0; i < 1000000; i++ )
tmp.push_back('0');
return tmp;
}


You must have an old compiler (VC6 perhaps?). Upgrade, and the C++
version should become faster than the Java one.

The problem is that VC6's std::string didn't perform exponential
growth - it favours memory usage over speed (contrary to most users
hopes). VC7 (and other compilers) fix this problem by using
exponential growth (similar to StringBuffer, but in C++ hence
faster!).

Tom
 
T

tom_usenet

Did you try changing this to "string sTmp(1000000, ' ');" to make the
comparison a bit fairer ??

That would make it less fair, surely? He's just using a
poor-for-append std::string implementation.

Tom
 
J

Johan Nilsson

tom_usenet said:
That would make it less fair, surely? He's just using a
poor-for-append std::string implementation.

Why is that? The StringBuffer is obviously initially sized to hold all
data - so why not do the same thing with the string (but I would agree that
calling reserve(1000000) separately on the string would be even faster, as
someone else suggested).

You might be correct about the implementation though.

// Johan
 
T

tom_usenet

Why is that? The StringBuffer is obviously initially sized to hold all
data - so why not do the same thing with the string (but I would agree that
calling reserve(1000000) separately on the string would be even faster, as
someone else suggested).

Whoops, I didn't spot the size parameter passed to the StringBuffer
constructor - I assumed he was default constructing.

In that case, std::string should catch up, even with a poor
implementation.

Tom
 
K

kld

You are all the right. I do not have to use reserve, in addition my
compilation was debug. These is the results in release mode.


Test: JAVA: 32.3 seconds -- C++: 125.8 seconds

JAVA: 32.3 seconds
public static String fu()
{
StringBuffer sTmp = new StringBuffer();
for ( int i = 0; i < 1000000; i++ )
sTmp.append("0");
return sTmp.toString();
}

C++: 125.8 seconds
string fu()
{
string sTmp;
for ( int i = 0; i < 1000000; i++ )
sTmp += "0";
return sTmp;
}
 
K

kld

I want to say you, than I do not want to make a race java vs c++. I
only want to make a good program in c++.
Thanks.
 
K

Karl Heinz Buchegger

kld said:
You are all the right. I do not have to use reserve, in addition my
compilation was debug. These is the results in release mode.

Test: JAVA: 32.3 seconds -- C++: 125.8 seconds

and now try this variation
string fu()
{
string sTmp;

sTmp.reserve( 1000000 );
for ( int i = 0; i < 1000000; i++ )
sTmp += "0";
return sTmp;
}

If I do it on my compiler (VC6.0) the runtime
in relase mode drops from 86 sec to 0.06 sec
 
T

tom_usenet

I want to say you, than I do not want to make a race java vs c++. I
only want to make a good program in c++.

In that case, bear in mind that std::string doesn't necessarily have
good "growth" behaviour (although it does on implementations I've seen
other than VC6's), so make occasional manual calls to reserve to make
sure the size increases exponentially. e.g.

string fu()
{
string sTmp;
for ( int i = 0; i < 1000000; i++ )
{
if (sTmp.size() == sTmp.capacity())
{
//more than double the capacity
sTmp.reserve(4 + sTmp.capacity() * 2);
}
sTmp += "0";
}
return sTmp;
}

It's a pain, but you can avoid having to do it by upgrading your
library (either to STLport or a more recent Dinkumware library) or by
upgrading to a more recent version of MSVC (such as 7 or 7.1).

Tom
 
K

Karl Heinz Buchegger

kld said:
This is an example. It can happen in real programming when the string
become very long, by example a large dynamic html page.
Thanks.

But I think even you would admit that adding a single
character a million times to always the same string
happens very infrequently in real programming.
 
K

kld

Yes, I am using VC 6.0

Try this too:

vector<char> fu()
{
vector<char> tmp;
for ( int i = 0; i < 1000000; i++ )
tmp.push_back('0');
return tmp;
}


You must have an old compiler (VC6 perhaps?). Upgrade, and the C++
version should become faster than the Java one.

The problem is that VC6's std::string didn't perform exponential
growth - it favours memory usage over speed (contrary to most users
hopes). VC7 (and other compilers) fix this problem by using
exponential growth (similar to StringBuffer, but in C++ hence
faster!).

Tom
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top