Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

performance of concatening strings by operator+ or stringstream

2,082 views
Skip to first unread message

gas...@hotmail.com

unread,
Oct 2, 2009, 7:58:45 AM10/2/09
to
Dear all,

I was under the impression that stringstream was also good in building
strings. However in a test it seems that the stringstream is actual 4
times slower. Is this by design (e.g. stringstream is better in
parsing and streaming of varios types, while string building can
better be performed with just operator+= ) ?

const size_t g_nConcatMax(100000);
const std::string g_str("Hello world");

std::string ConcatPlus()
{
std::string str;

for (size_t n = 0; n != g_nConcatMax; ++n)
{
str += g_str;
}

return str;
}


std::string ConcatStream()
{
std::stringstream sstr;

for (size_t n = 0; n != g_nConcatMax; ++n)
{
sstr << g_str;
}

return sstr.str();
}

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Nick Hounsome

unread,
Oct 2, 2009, 1:47:06 PM10/2/09
to
On 2 Oct, 12:58, "gast...@hotmail.com" <gast...@hotmail.com> wrote:
> Dear all,
>
> I was under the impression that stringstream was also good in building
> strings. However in a test it seems that the stringstream is actual 4
> times slower. Is this by design (e.g. stringstream is better in
> parsing and streaming of varios types, while string building can
> better be performed with just operator+= ) ?
>
> const size_t g_nConcatMax(100000);
> const std::string g_str("Hello world");
>
> std::string ConcatPlus()
> {
> std::string str;
>
> for (size_t n = 0; n != g_nConcatMax; ++n)
> {
> str += g_str;
> }
>
> return str;
>
> }
>
> std::string ConcatStream()
> {
> std::stringstream sstr;
>
> for (size_t n = 0; n != g_nConcatMax; ++n)
> {
> sstr << g_str;
> }
>
> return sstr.str();
>
> }

There is no stringstream::operator<<

You are calling the base ostream::operator<< and this obviously
doesn't know that it is going to a string and so cannot optimize it -
it has to work with the buffer abstraction streambuf implemented by
stringbuf one character at a time.

Ulrich Eckhardt

unread,
Oct 2, 2009, 10:26:34 PM10/2/09
to
gas...@hotmail.com wrote:
> I was under the impression that stringstream was also good in building
> strings. However in a test it seems that the stringstream is actual 4
> times slower.

If you need good performance or are composing large amounts of text,
stringstreams in general may not be the best of ideas, but in any case it
depends on the actual implementation. Which implementation is that factor
from, btw?

> Is this by design (e.g. stringstream is better in parsing and streaming
> of varios types, while string building can better be performed with just
> operator+= ) ?

I'd say neither perform really well, because both typically require
reallocation and the ensuing copying of existing data when the buffers are
full.

If you want performance on large amounts of data, I'd suggest streaming into
a streambuffer that uses a deque<char_type> as storage. This container
stores its data in chunks of a fixed size, avoiding reallocation and copying
for new data. Then, avoid copying that data, both by e.g. returning it as
string from a function or by even converting it to a string in the first
place.

Uli

gas...@hotmail.com

unread,
Oct 4, 2009, 5:39:10 PM10/4/09
to
> If you need good performance or are composing large amounts of text,
> stringstreams in general may not be the best of ideas, but in any case it
> depends on the actual implementation. Which implementation is that factor
> from, btw?

This is tested on VStudio2008. Indeed I was thinking that the string
library needs a lot of reallocations so a stringstream might be better
(performance wise). But obviously other factors of the stringstream
account as well. Atm we do not need optimal performance but I was just
thinking of a general guide line for concatening strings.

Ulrich Eckhardt

unread,
Oct 7, 2009, 8:50:52 AM10/7/09
to
gas...@hotmail.com wrote:
> This is tested on VStudio2008.

At least VS2005 does some runtime validation of iterators and such stuff
that imposes a performance penalty even if not compiling for debugging. You
need to #define a macro to really turn that off.

> Indeed I was thinking that the string
> library needs a lot of reallocations so a stringstream might be better
> (performance wise). But obviously other factors of the stringstream
> account as well. Atm we do not need optimal performance but I was just
> thinking of a general guide line for concatening strings.

General guideline: Don't.

If you have to, just use operator+. If this becomes a performance
bottleneck, try preallocating with reserve() first.

Otherwise, if you have lots of strings to concatenate, refer to the general
guideline. The point is that you typically don't actually need them in one
string. If you want to write them to a file or to the screen, you can just
as easily iterate over a list of strings and handle them separately.

For large texts, there is also the 'rope' class in the STL, which you might
want to use or at least take a look at. However, that part of the STL is
not part of the C++ standard library, which complicates things a bit.

Uli

--
Sator Laser GmbH
Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932

gas...@hotmail.com

unread,
Oct 8, 2009, 11:12:39 PM10/8/09
to
> At least VS2005 does some runtime validation of iterators and such stuff
> that imposes a performance penalty even if not compiling for debugging.
You
> need to #define a macro to really turn that off.
This safe iterator stuff is practically impossible to turn off, or u
must recompile the msvcp*.dll's urself. If iterators are passed over
module boundaries with different compile flags, a crash is
guaranteed.

However it may be other reasons which contribute. Steping thru the
difficult readable STL of VStudio, there seems a lot going on just
adding a character to a stream.

Guideline would be to use operator+. Strings are most used in
displaying texts in GUI's, so performance isn't that critical (but
things u get for free are always welcome, like using const& in
function arguments instead of copying the object).

Rope class is a SGI extension.

--

Ulrich Eckhardt

unread,
Oct 9, 2009, 5:18:46 PM10/9/09
to
gas...@hotmail.com wrote:
> This safe iterator stuff is practically impossible to turn off, or u
> must recompile the msvcp*.dll's urself. If iterators are passed over
> module boundaries with different compile flags, a crash is
> guaranteed.

I wasn't aware that it is that difficult... :/

> Steping thru the difficult readable STL of VStudio, there seems a
> lot going on just adding a character to a stream.

[...]


> Rope class is a SGI extension.

Wait: The STL, created by Hewlett-Packard, now hosted at SGI's, is _the_
STL, _the_ "Standard Template Library". The STL contains a rope class. The
STL is not an implementation of the C++ standard library though, even
though its name contains the term "standard". Actually, it is older than
that, and many parts of the C++ stdlib initially came from the STL, with
the rope class being one part of the STL that did not make it into the
standard.

As such, there is no "STL of VStudio", it's an implementation of the C++
stdlib (from Dinkumware, actually). Neither can you call the rope class an
SGI extension to the C++ standard, because the STL is not an implementation
of the C++ standard library.

That said, the confusion between the STL and the C++ standard library is
common.

Uli

--
Sator Laser GmbH
Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932

Nick Hounsome

unread,
Oct 11, 2009, 11:53:21 PM10/11/09
to
On 4 Oct, 22:39, "gast...@hotmail.com" <gast...@hotmail.com> wrote:
> > If you need good performance or are composing large amounts of text,
> > stringstreams in general may not be the best of ideas, but in any case it
> > depends on the actual implementation. Which implementation is that factor
> > from, btw?
>
> This is tested on VStudio2008. Indeed I was thinking that the string
> library needs a lot of reallocations so a stringstream might be better
> (performance wise). But obviously other factors of the stringstream
> account as well. Atm we do not need optimal performance but I was just
> thinking of a general guide line for concatening strings.

Appologies for the slip up earlier - There is, of course, no
ostream::operator<< - They are a set of free functions. But the basic
message is still correct. A string stream can't be optimized because
it has to call virtual methods on a stringbuf* that could, in
principle, be replaced with a derived class with overrides that do
anything (Although this all seems a bit far fetched to me and unlikely
to work well).

The std::string library will not normally allocate every time a string
is concatenated.
A common implementation strategy is to allocate the minimum of the
required new size and double the current capacity every time it is
found to be too small.

0 new messages