From 9ba45189c76373d0464cc06902270914888162a3 Mon Sep 17 00:00:00 2001 From: Luboš Luňák Date: Thu, 6 Jan 2022 14:15:44 +0100 Subject: make SdrCustomShapeGeometryItem sortable and fast (bsc#1183308) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The document contains a complex graphic consisting of many shapes, and SfxItemPool tries to avoid duplicates by checking for equality. And SdrCustomShapeGeometryItem contains a UNO sequence as data, and comparing those is non-trivial. Make the item sortable, which should make things faster, and use anyLess() for the ordering. Additionally first check the size of the list of property names the class keeps for an easy fast return. Change-Id: I49220e589b6510c6f1f40d584301be83367fb5a4 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/128047 Tested-by: Jenkins Reviewed-by: Luboš Luňák --- include/svx/sdasitm.hxx | 3 +++ svx/source/items/customshapeitem.cxx | 32 ++++++++++++++++++++++++++++---- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/include/svx/sdasitm.hxx b/include/svx/sdasitm.hxx index 620e805b5813..ebd022980e6e 100644 --- a/include/svx/sdasitm.hxx +++ b/include/svx/sdasitm.hxx @@ -62,6 +62,9 @@ private: SdrCustomShapeGeometryItem & operator =(SdrCustomShapeGeometryItem &&) = delete; // due to SfxPoolItem virtual bool operator==( const SfxPoolItem& ) const override; + virtual bool operator<( const SfxPoolItem& ) const override; + virtual bool IsSortable() const override { return true; } + virtual bool GetPresentation(SfxItemPresentation ePresentation, MapUnit eCoreMetric, MapUnit ePresentationMetric, OUString &rText, const IntlWrapper&) const override; diff --git a/svx/source/items/customshapeitem.cxx b/svx/source/items/customshapeitem.cxx index 733b30f29e47..0bba5ca6eb33 100644 --- a/svx/source/items/customshapeitem.cxx +++ b/svx/source/items/customshapeitem.cxx @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -216,12 +217,35 @@ void SdrCustomShapeGeometryItem::ClearPropertyValue( const OUString& rPropName ) SdrCustomShapeGeometryItem::~SdrCustomShapeGeometryItem() { } + bool SdrCustomShapeGeometryItem::operator==( const SfxPoolItem& rCmp ) const { - bool bRet = SfxPoolItem::operator==( rCmp ); - if ( bRet ) - bRet = static_cast(rCmp).aPropSeq == aPropSeq; - return bRet; + if( !SfxPoolItem::operator==( rCmp )) + return false; + const SdrCustomShapeGeometryItem& other = static_cast(rCmp); + // This is called often by SfxItemPool, and comparing uno sequences is relatively slow. + // Optimize by checking the list of properties that this class keeps for the sequence, + // if the sizes are different, the sequences are different too, which should allow a cheap + // return for many cases. + if( aPropHashMap.size() != other.aPropHashMap.size()) + return false; + if( aPropPairHashMap.size() != other.aPropPairHashMap.size()) + return false; + return aPropSeq == other.aPropSeq; +} + +bool SdrCustomShapeGeometryItem::operator<( const SfxPoolItem& rCmp ) const +{ + assert(dynamic_cast( &rCmp )); + const SdrCustomShapeGeometryItem& other = static_cast(rCmp); + // Again, optimize by checking the list of properties and compare by their count if different + // (this is operator< for sorting purposes, so the ordering can be somewhat arbitrary). + if( aPropHashMap.size() != other.aPropHashMap.size()) + return aPropHashMap.size() < other.aPropHashMap.size(); + if( aPropPairHashMap.size() != other.aPropPairHashMap.size()) + return aPropPairHashMap.size() < other.aPropPairHashMap.size(); + return comphelper::anyLess( css::uno::makeAny( aPropSeq ), + css::uno::makeAny( other.aPropSeq )); } bool SdrCustomShapeGeometryItem::GetPresentation( -- cgit