* Francesco: [snip]
I've tried to implement and profile at once all three possibilities
(inserters, toString function with the default + operator, direct
stringstream usage). To be fair between the measurements, I've helped
the "inserters" version as much as possible (since the toString needs
to be called fewer times).
Well, you haven't (see below).
But it doesn't matter here.
I see what you mean: I did not help then as much as possible. In fact,
I helped them as much as I could (actually, I did it by overloading
operator<<() for string, const char* and char, thus avoiding to create
a further ostringstream in those cases).
Not at all. Your timings show the inserters to be superior. And among the two
inserter approaches, which are fastest, the one that doesn't do a lot of extra
needless work per insertion, is -- not unexpectedly! -- slightly faster.
Well, yes, slightly faster. But such a difference came as "more or
less" to my eyes, since the "winner" alternated between different
runs ;-)
Of course, I didn't consider the direct ostringstream usage into the
"more or less equal timings" statement, that was the reference
timing ;-)
It would, yes.
I guessed right, but I didn't completely get the point. Now I filled
the gap, read below.
Generally that's a good idea, but invoking std:
stringstream in each << and
then for each such result extracting a string and copying it plus a
concatenation, is ungood for efficiency because, as Jerry remarked else-thread
or was it up-thread, you're then doing much extra, needless work.
I thought I simply couldn't avoid it (Jerry suggested me to use
ostringstream directly) - and after all, I was looking for ease of
notation (that is, hiding the use of an ostringstream, but still using
<< on the strings). I didn't really consider timing issues before of
your post,
Now I also realize that I simply rehearsed the thread about building
strings on the fly with the wrong supposition that I could take
advantage of applying the << operators directly to the strings.
Not bad, in any case. This gives me the occasion to merge the
improvements I made to my logger class (there in that other thread)
with your suggestions.
Instead do something like (off the cuff)
class S
{
private:
std:
stringstream myStream;
public:
S() {}
S( char const s[] ): myStream( s ) {}
S( std::string const& s ): myStream( s ) {}
template< typename T >
S& operator<<( T const& v )
{
myStream << v;
return *this;
}
std::string str() const { return myStream.str(); }
operator std::string () const { return myStream.str(); }
};
Here above you made explicit the point that I missed to get in your
previous post.
While in my insertion sequences the leftmost object was a string, in
your code it was an "S" object. I missed to understand it, I replaced
it with a couple of question marks in my mind and I went on :-/
That's pretty bad, because it means that I completely mistaken the
very beginning of that other thread, which I realize I have sort of
hijacked :-/
You haven't tested it. Your timings are dominated by the inefficient conversion
from number to string, and you have very short strings and low number of them,
avoiding all three factors that might make that difference count. It's possible
that you'll see it if you use e.g. sprintf to implement the conversion, and/or
if you use longer strings, and/or if you have more of them.
That means that I should prefer sprintf over ostringstream to get
faster conversions?
I suppose so. But if I use it I wouldn't be taking advantage of stream
manipulators and formatting, I suppose, and I just decided to allow
them in.
I'll keep sprintf out, getting a performance close to the direct
ostringstream usage will be more than enough.
[ snipped code and test results of mine ]
As you can see even from this test, value based concatenation (your UseToString)
is generally slowest.
But without adding << functionality, value based concatenation is all that you
have for std::string in an expression.
Now I understand. Thanks a lot, I've learned a lot of things here,
once more.
I will extend your S class and I'll post it here, shall it be of some
use for anybody else stomping on this thread.
Best regards,
Francesco