diff options
author | Armin Le Grand (allotropia) <armin.le.grand.extern@allotropia.de> | 2023-08-10 15:54:23 +0200 |
---|---|---|
committer | Armin Le Grand <Armin.Le.Grand@me.com> | 2023-08-10 20:43:21 +0200 |
commit | 23d1395a7856119173b37a6d787171f519554623 (patch) | |
tree | 12205fad4b6d8ef5ddc0394eb22ae30427257b2e /include | |
parent | ce2d9f5dd4b6a26847c4779bce4866d969ff4400 (diff) |
ITEM: improve SfxItemSet notification callback
When browsing cachegrind data I stumbled over the notification
callback used by Writer in SfxItemSet::Changed. That is a
virtual method that gets called in quite some places to forward
item changes, SW uses it to record these.
For that purpose always (quite some) data gets prepared without
checking if this is necessary, this uses calls to ::Get and
::GetDefaultItem to have either the old or new Item from the
parent or default (pool).
This is not needed - except for Writer. Even there this
mechanism is not always active. Thus I:
- removed SfxItemSet::Changed, replaced with a settable callback
member of type std::function<...>. Thus one less virtual function
and depenence in SfxItemSet
- added a callback functor to SwAttrSet that can be set at the
SfxItemSet it is derived from
- setting/releasing this only in used cases. It is not even used
all the time in SW.
- moved the creation/processing of needed data to a member
function in SW (SwAttrSet::changeCallback). All processing and
evtl. needed data is now created there - on demand.
- adapted all places in SfxItemSet where that mechanism is used
to only call it if set & without pre-calculating anything
- since all former calls/usages were pretty similar I could put
all of this to SwAttrSet::changeCallback
This leads to use that only when needed now. Naturally, SW will
potentially profit less than the other apps.
Here are callgrind numbers with this change using OfficeStart,
DocLoad, DocClose, OfficeShutdown. This change also has potential
avantages @runtime/UI which also did all preparations to call
SfxItemSet::Changed all the time:
Writer doc: 0,9907 ~1%
old: 93842 mio
new: 92971 mio
Draw/Impress doc: 0,9971 ~2,8%
old: 170023 mio
new: 169544 mio
::Get reduces from 1416103 to 293874 calls
::GetDefaultItem reduces from 2252336 to 1927209 calls (nearly half)
Calc doc: 0.9868 ~1,3%
old: 194708 mio
new: 192130 mio
::Get reduces from 882298 to 880087 calls
::GetDefaultItem reduces from 4611901 to 2633555 calls (nearly half)
Of course this highly depends on the used test documents, so it can
only be a excerpt result.
Also adapted SfxItemSet::MergeRange a little bit: Do nothing not only
when a single new slot is already contaioned, but check if all slots
are already present. This works well and fast using the formally added
caching mechanism.
Change-Id: I4d369d2e5b21aa7a21687177518150515e3de954
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155559
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
Diffstat (limited to 'include')
-rw-r--r-- | include/svl/itemset.hxx | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/include/svl/itemset.hxx b/include/svl/itemset.hxx index 468893557b5e..a3736427b002 100644 --- a/include/svl/itemset.hxx +++ b/include/svl/itemset.hxx @@ -42,9 +42,20 @@ class SAL_WARN_UNUSED SVL_DLLPUBLIC SfxItemSet const SfxItemSet* m_pParent; ///< derivation sal_uInt16 m_nCount; ///< number of items sal_uInt16 m_nTotalCount; ///< number of WhichIDs, also size of m_ppItems array + + // bitfield (better packaging if a bool needs to be added) + bool m_bItemsFixed : 1; ///< true if this is a SfxItemSetFixed object, so does not *own* m_ppItems + SfxPoolItem const** m_ppItems; ///< pointer to array of items, we allocate and free this unless m_bItemsFixed==true WhichRangesContainer m_pWhichRanges; ///< array of Which Ranges - bool m_bItemsFixed; ///< true if this is a SfxItemSetFixed object + + // Notification-Callback mechanism for SwAttrSet in SW, functionPtr for callback + std::function<void(const SfxPoolItem*, const SfxPoolItem*)> m_aCallback; + +protected: + // Notification-Callback mechanism for SwAttrSet in SW + void setCallback(const std::function<void(const SfxPoolItem*, const SfxPoolItem*)> &func) { m_aCallback = func; } + void clearCallback() { m_aCallback = nullptr; } friend class SfxItemPoolCache; friend class SfxAllItemSet; @@ -59,9 +70,6 @@ private: const SfxItemSet& operator=(const SfxItemSet &) = delete; protected: - // Notification-Callback - virtual void Changed( const SfxPoolItem& rOld, const SfxPoolItem& rNew ); - void PutDirect(const SfxPoolItem &rItem); virtual const SfxPoolItem* PutImpl( const SfxPoolItem&, sal_uInt16 nWhich, bool bPassingOwnership ); |