sc-perf: bundle SdrObject::BroadcastObjectChange() calls during Save

Test doc https://bugs.documentfoundation.org/attachment.cgi?id=128252 from
https://bugs.documentfoundation.org/show_bug.cgi?id=103493

ScPostIt::CreateCaptionFromInitData() called through
ScDocument::CreateAllNoteCaptions()

          Incl.     Self  Called
Before:
326,418,830,114  487,308   6,645
After:
145,055,889,118  511,681   6,645

Reduced to 44% or speed-up by factor 2.25

Overall ScDocShell::SaveXML()
Before: 370,433,720,090
 After: 189,120,982,786

Reduced to 51% or speed-up by factor 1.96

There's still too much broadcasting to accessibility going on though..

Change-Id: I50555fd9751ac24006cc96b2fa8e82b32aba0748
This commit is contained in:
Eike Rathke
2016-11-19 01:11:21 +01:00
parent 87c67a4ad3
commit 451c4cccc7
3 changed files with 54 additions and 0 deletions

View File

@@ -295,6 +295,7 @@ private:
friend class SdrObjListIter;
friend class SdrVirtObj;
friend class SdrRectObj;
friend class SdrDelayBroadcastObjectChange;
protected:
Rectangle aOutRect; // surrounding rectangle for Paint (incl. LineWdt, ...)
@@ -351,6 +352,11 @@ protected:
// #i25616#
bool mbSupportTextIndentingOnLineWidthChange : 1;
private:
bool mbDelayBroadcastObjectChange : 1;
mutable bool mbBroadcastObjectChangePending : 1;
protected:
// on import of OLE object from MS documents the BLIP size might be retrieved,
// in this case the following member is initialized as nonempty rectangle
Rectangle maBLIPSizeRectangle;
@@ -968,6 +974,20 @@ private:
bool mbDoNotInsertIntoPageAutomatically;
};
/** Suppress BroadcastObjectChange() until destruction of the (last) instance.
Prevents multiple broadcasts for a sequence of calls that would trigger a
broadcast each. Instances may be nested in levels, the outer instance will
trigger the final broadcast.
*/
class SVX_DLLPUBLIC SdrDelayBroadcastObjectChange
{
SdrObject& mrObj;
bool mbOldDelayBroadcastObjectChange;
public:
SdrDelayBroadcastObjectChange( SdrObject& rObj );
~SdrDelayBroadcastObjectChange();
};
struct SdrObjCreatorParams
{
sal_uInt32 nInventor;

View File

@@ -640,6 +640,11 @@ void ScPostIt::CreateCaptionFromInitData( const ScAddress& rPos ) const
ScNoteCaptionCreator aCreator( mrDoc, rPos, maNoteData );
if( maNoteData.mpCaption )
{
// Prevent triple change broadcasts of the same object, which
// during Save triggered by ScDocument::CreateAllNoteCaptions()
// creates a major performance bottleneck.
SdrDelayBroadcastObjectChange aDelayChange( *maNoteData.mpCaption);
ScCaptionInitData& rInitData = *maNoteData.mxInitData;
// transfer ownership of outliner object to caption, or set simple text

View File

@@ -302,6 +302,8 @@ SdrObject::SdrObject() :
,pGrabBagItem(nullptr)
,mnNavigationPosition(SAL_MAX_UINT32)
,mnLayerID(0)
,mbDelayBroadcastObjectChange(false)
,mbBroadcastObjectChangePending(false)
,mpSvxShape( nullptr )
,maWeakUnoShape()
,mbDoNotInsertIntoPageAutomatically(false)
@@ -880,6 +882,12 @@ void SdrObject::BroadcastObjectChange() const
if( pModel && pModel->isLocked() )
return;
if (mbDelayBroadcastObjectChange)
{
mbBroadcastObjectChangePending = true;
return;
}
bool bPlusDataBroadcast(pPlusData && pPlusData->pBroadcast);
bool bObjectChange(IsInserted() && pModel);
@@ -3092,6 +3100,27 @@ bool SdrObject::HasText() const
return false;
}
SdrDelayBroadcastObjectChange::SdrDelayBroadcastObjectChange( SdrObject& rObj ) :
mrObj(rObj), mbOldDelayBroadcastObjectChange( rObj.mbDelayBroadcastObjectChange)
{
mrObj.mbDelayBroadcastObjectChange = true;
}
SdrDelayBroadcastObjectChange::~SdrDelayBroadcastObjectChange()
{
if (!mbOldDelayBroadcastObjectChange)
{
mrObj.mbDelayBroadcastObjectChange = false;
if (mrObj.mbBroadcastObjectChangePending)
{
mrObj.mbBroadcastObjectChangePending = false;
mrObj.BroadcastObjectChange();
}
}
}
SdrObject* SdrObjFactory::CreateObjectFromFactory( sal_uInt32 nInventor, sal_uInt16 nObjIdentifier, SdrPage* , SdrModel* )
{
SdrObjCreatorParams aParams { nInventor, nObjIdentifier };