QCString construction
David Faure
faure at kde.org
Sun Feb 11 00:11:52 CET 2007
On Saturday 10 February 2007, Roger Larsson wrote:
> On Saturday 10 February 2007 02:16, David Faure wrote:
> >
> > One for Qt itself: why does QCString use the slow way when duplicating
> > QCStrings? (I know that QCString tmp( s1 ); is shallow copy, but the next
> > line calls operator+= which calls detach) Unless someone spots a flaw in
> > this patch I'll be posting it to TT (and I'm testing my local kde with it
> > starting from tomorrow ;)
>
> I think it is because all these will require detach, so a new string has to be
> allocated anyway.
Can't see the relation. Yes a new string is allocated anyway, but in both cases
it won't make room for the added string before operator+ is called -- read the code, man ;)
> But will it be large enough to avoid an extra copy when appending?
> The tmp constructors could use a hint that they will grow.
> That could be done in the append anyway...
They could. But that's kind of the next step.
> Have you benchmarked that your Qt patch really is faster?
I think my other benchmark proves quite well that qstrlen is at fault,
comparing the two ways of doing string copying. But since you want proof,
here it is:
inline const QCString initialOperatorPlus( const QCString &s1, const QCString &s2 )
{
QCString tmp( s1.data() );
tmp += s2;
return tmp;
}
inline const QCString myOperatorPlus( const QCString &s1, const QCString &s2 )
{
QCString tmp( s1 );
tmp += s2;
return tmp;
}
[...]
QCString astr = charData;
QCString bstr = charData;
time.restart();
for ( uint i = 0; i < numIterations; ++i ) {
QCString cstr = initialOperatorPlus(astr, bstr);
assert( cstr[0] == 'A' );
assert( cstr[dataLength-1] == 'A' );
assert( cstr[2*(dataLength-1)] == '\0' );
}
qDebug( "Initial operator+ took %i milliseconds", time.elapsed() );
time.restart();
for ( uint i = 0; i < numIterations; ++i ) {
QCString cstr = myOperatorPlus(astr, bstr);
assert( cstr[0] == 'A' );
assert( cstr[dataLength-1] == 'A' );
assert( cstr[2*(dataLength-1)] == '\0' );
}
qDebug( "My operator+ took %i milliseconds", time.elapsed() );
Results:
Initial operator+ took 956 milliseconds
My operator+ took 731 milliseconds
(... still slow because QCString::operator+=( const char *str ) is called, which calls qstrlen(str), but I can't avoid that one;
stupid qcstring doesn't store its own length.)
Yet, it is a 23% speed improvement already.
--
David Faure, faure at kde.org, sponsored by Trolltech to work on KDE,
Konqueror (http://www.konqueror.org), and KOffice (http://www.koffice.org).
More information about the Kde-optimize
mailing list