Discussion:
how do i create a ostringstream with pre-allocated memory buffer
(too old to reply)
Siemel Naran
2003-09-09 17:56:35 UTC
Permalink
unsigned int size = 300000; // this value actually comes from
another func
std::string s;
s.resize(size);
std::ostringstream os(s);
The line s.resize(size) gives 's' a size of 3 million elements. The last
line makes a copy of 's', and if you string is not reference counted, then
it copies all 3 million chars in the string. Could be bad performance.

If you say s.reserve(size) then 's' has 0 chars but space to hold 3 million.
The last line still makes a copy of 's', but per table 43 of the standard,
the capacity() in the copied string may still be zero, not 3 million. So
you still have bad performance.

I think that an enhancement to std::basic_stringbuf and the corresponding
iostream classes might be the answer.

--
+++++++++++
Siemel Naran


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Paul Woods
2003-09-10 18:45:48 UTC
Permalink
Post by Siemel Naran
I think that an enhancement to std::basic_stringbuf and the corresponding
iostream classes might be the answer.
Siemel Naran - Thanks for the reply.

I agree with you. It would be nick if basic_stringbuf had a .reserve member.

Thanks
Paul Woods

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Ulrich Eckhardt
2003-09-10 18:51:40 UTC
Permalink
I need to write data to a std::ostringstream object. My problem is
that the re-allocations are causing poor performance.
I have seen really poor performance only with the stdlib that came with
MSVC6 (a vory old version of Dinkumware's) which always added 32 byte to
the internal string when it grew too large. I switched to STLport and in
the run fixed quite some more problems with that old lib.
But, I already know approximately how much data will be written to the
ostringstream.
I wrapped a string by reference in a streambuffer like this:

class stringrefbuf: stringbuf
{
public:
stringrefbuf(string& sref):m_sref(sref){}
private:
virtual int_type overflow(int_type c)
{
if(c!=traits_type::eof())
m_sref += traits_type::to_char_type(c);
return traits_type::not_eof(c);
}
// TODO: xsputn() for performance
string& m_sref;
}

#if OLD
ostringstream str;
fill(str);
string s = str.str();
#else
string s;
// s.reserve()
stringrefbuf buf(s);
ostream str(&buf);
fill(str);
#endif

Of course, I also added a new streamtype which already has such a
streambuffer. In that case the above boils down to:

string s;
ostringrefstream str(s);
fill(str);

I have been wondering why there is no such thing in boost, it would at
least be a nice compliment to their format-lib. Is there something so
seriously flawed in that design ?

Uli
--
Questions ?
see C++-FAQ Lite: http://parashift.com/c++-faq-lite/ first !


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