[Libreoffice] inconsistency between rtl::OString/rtl::OUString and optimization opportunities ?
Caolán McNamara
caolanm at redhat.com
Wed Aug 31 03:04:00 PDT 2011
So, playing around with the sal string classes I see that...
rtl_string_new_WithLength/rtl_uString_new_WithLength create an
rtl/String/rtl_uString of the given length, but set the full buffer
contents to 0s[1]
meanwhile I see that we have x_rtl_uString_new_WithLength in
inc/i18nutil/x_rtl_ustring.h which is a non-zeroed out variant of
rtl_uString_new_WithLength so there's an uninitialized buffer available
to play with.
We can assign ownership of the rtl_uString to an OUString with
OUString( rtl_uString * str, __sal_NoAcquire ) and skip calling acquire,
i.e. OUString has *two* methods to take ownership of a rtl_uString
without calling acquire.
the public OUString( rtl_uString * str, __sal_NoAcquire )
the private OUString( rtl_uString * value, DO_NOT_ACQUIRE * )
as well as the usual add-add-refcount version of
OUString( rtl_uString * str )
While OString has only the private
OString( rtl_String * value, DO_NOT_ACQUIRE * )
as well as the usual add-add-refcount version of
OString( rtl_String * str ), so the same hack isn't available.
I'm vaguely thinking of moving that i18nutil x_rtl stuff into
comphelper/string or something, hard-coding its refcount argument to 0
or 1 and fixing up its uses to consistently use one or the other public
OUString acquire/noacquire ctors and add a OString variant so that
either of the belows is possible to skip copying buffers around the
place.
#if thinko-one
rtl_String *pStr = foo_rtl_string_new_WithLength(nLen/*, refCount=0*/);
//call acquire, refCount of 1, OString::dtor destroys buffer
rtl::OString aRet(pStr);
pStr->length = rStrm.Read(pStr->buffer, nLen);
#else
rtl_String *pStr = foo_rtl_string_new_WithLength(nLen/*, refCount=1*/);
//don't call acquire, refCount stays 1, OString::dtor destroys buffer
rtl::OString aRet(pStr, SAL_NO_ACQUIRE);
pStr->length = rStrm.Read(pStr->buffer, nLen);
#endif
//if unlikely length != nLen make deep copy of string to release excess
//mem, nobody seems to worry about excess for rtl::O[U]String buffers,
//but much less opportunity to have a large chunk of unused
//buffer there.
C.
[1] with a loop, I suppose its no real optimization there to use memset
or rtl_allocateMemory for that case ?
More information about the LibreOffice
mailing list