diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2019-04-20 08:32:33 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2019-04-20 18:18:20 +0200 |
commit | 003d11f410b7e515981b3efbd65d936d94d87121 (patch) | |
tree | d15fffce95dfc4b115b53cfb3b6924a26a506231 /svl | |
parent | a0d14926ab3d5e84cefe2b349c451edf6666a392 (diff) |
tdf#81765 slow loading of .ods with >1000 of conditional formats
This takes the loaing time from 1m38 to 15s.
Speed up finding existing pool items in the pool by storing a
sorted_vector, sorted by a compare operator on the item.
memcmp is faster than operator< on std::vector because operator< seems
to be trying to use some kind of lexicographical compare
Change-Id: Id72527106d604adb8cd2d158bb42f89e2b16a85d
Reviewed-on: https://gerrit.libreoffice.org/71009
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'svl')
-rw-r--r-- | svl/source/inc/poolio.hxx | 30 | ||||
-rw-r--r-- | svl/source/items/itempool.cxx | 23 | ||||
-rw-r--r-- | svl/source/items/poolio.cxx | 1 |
3 files changed, 47 insertions, 7 deletions
diff --git a/svl/source/inc/poolio.hxx b/svl/source/inc/poolio.hxx index 8eef10c5af96..805406365284 100644 --- a/svl/source/inc/poolio.hxx +++ b/svl/source/inc/poolio.hxx @@ -20,6 +20,7 @@ #ifndef INCLUDED_SVL_SOURCE_INC_POOLIO_HXX #define INCLUDED_SVL_SOURCE_INC_POOLIO_HXX +#include <sal/log.hxx> #include <svl/itempool.hxx> #include <svl/SfxBroadcaster.hxx> #include <tools/debug.hxx> @@ -32,6 +33,13 @@ class SfxItemPoolUser; static const sal_uInt32 SFX_ITEMS_DEFAULT = 0xfffffffe; +struct CompareSortablePoolItems +{ + bool operator()(SfxPoolItem const* lhs, SfxPoolItem const* rhs) const + { + return (*lhs) < (*rhs); + } +}; /** * This array contains a set of SfxPoolItems, if those items are * poolable then each item has a unique set of properties, and we @@ -42,6 +50,7 @@ struct SfxPoolItemArray_Impl { private: o3tl::sorted_vector<SfxPoolItem*> maPoolItemSet; + o3tl::sorted_vector<const SfxPoolItem*, CompareSortablePoolItems> maSortablePoolItems; public: o3tl::sorted_vector<SfxPoolItem*>::const_iterator begin() const { return maPoolItemSet.begin(); } o3tl::sorted_vector<SfxPoolItem*>::const_iterator end() const { return maPoolItemSet.end(); } @@ -50,9 +59,26 @@ public: void clear(); size_t size() const {return maPoolItemSet.size();} bool empty() const {return maPoolItemSet.empty();} - void insert(SfxPoolItem* pItem) { maPoolItemSet.insert(pItem); } + void insert(SfxPoolItem* pItem) + { + maPoolItemSet.insert(pItem); + if (pItem->IsSortable()) + maSortablePoolItems.insert(pItem); + else + SAL_WARN_IF(maPoolItemSet.size() > 1024, "svl.items", "make this item sortable to speed up managing this set"); + } o3tl::sorted_vector<SfxPoolItem*>::const_iterator find(SfxPoolItem* pItem) const { return maPoolItemSet.find(pItem); } - void erase(o3tl::sorted_vector<SfxPoolItem*>::const_iterator it) { return maPoolItemSet.erase(it); } + const SfxPoolItem* findByLessThan(const SfxPoolItem* pItem) const + { + auto it = maSortablePoolItems.find(pItem); + return it == maSortablePoolItems.end() ? nullptr : *it; + } + void erase(o3tl::sorted_vector<SfxPoolItem*>::const_iterator it) + { + if ((*it)->IsSortable()) + maSortablePoolItems.erase(*it); + return maPoolItemSet.erase(it); + } }; struct SfxItemPool_Impl diff --git a/svl/source/items/itempool.cxx b/svl/source/items/itempool.cxx index b407889db8e0..67f141dbd16b 100644 --- a/svl/source/items/itempool.cxx +++ b/svl/source/items/itempool.cxx @@ -628,12 +628,25 @@ const SfxPoolItem& SfxItemPool::Put( const SfxPoolItem& rItem, sal_uInt16 nWhich } // 2. search for an item with matching attributes. - for (auto itr = rItemArr.begin(); itr != rItemArr.end(); ++itr) + if (rItem.IsSortable()) { - if (**itr == rItem) + auto pFoundItem = rItemArr.findByLessThan(&rItem); + if (pFoundItem) { - AddRef(**itr); - return **itr; + assert(*pFoundItem == rItem); + AddRef(*pFoundItem); + return *pFoundItem; + } + } + else + { + for (auto itr = rItemArr.begin(); itr != rItemArr.end(); ++itr) + { + if (**itr == rItem) + { + AddRef(**itr); + return **itr; + } } } } @@ -710,8 +723,8 @@ void SfxItemPool::Remove( const SfxPoolItem& rItem ) // See other MI-REF if ( 0 == rItem.GetRefCount() && nWhich < 4000 ) { - delete &rItem; rItemArr.erase(it); + delete &rItem; } return; diff --git a/svl/source/items/poolio.cxx b/svl/source/items/poolio.cxx index 478fb821d60d..a909450f4588 100644 --- a/svl/source/items/poolio.cxx +++ b/svl/source/items/poolio.cxx @@ -33,6 +33,7 @@ void SfxPoolItemArray_Impl::clear() { maPoolItemSet.clear(); + maSortablePoolItems.clear(); } sal_uInt16 SfxItemPool::GetFirstWhich() const |