diff options
author | Armin Le Grand (allotropia) <armin.le.grand.extern@allotropia.de> | 2024-04-22 15:16:42 +0200 |
---|---|---|
committer | Armin Le Grand <Armin.Le.Grand@me.com> | 2024-04-23 09:39:47 +0200 |
commit | fd2aaac24712550e4bbd349575192edb56bc94c9 (patch) | |
tree | 79616409ba266e8589e7af093a27f5a286693dae /svl | |
parent | a29d91ac403f1ed431ca95b8b9c290bd354c3ae7 (diff) |
ITEM: Add measurements for SfxItemSet usages (debug only)
I was wondering how much of that arrays of pointers
to SfxPoolItems is actually used in the SfxItemSets in
real office runtime, so I added code now to measure that.
It does use the state of the ItemSet at destruction,
so it is possible that items were added/removed which
are not covered, but most cases of internal usages do
not do that.
I then check/sort the collected data at office shutdown,
it will be printed as SAL_INFO when svl.items/vcl.items
is set, so use this to see the data.
This gives info about the average space utilization in
different ItemSets with different sizes, also gives an
insight about used ItemSet sizes and amount of their
usages.
Of course results differ from app to app and dependent
of what is done with the office, but interestingly when
using quite some files opening from all apps it
toggles/normalizes to something around 20-25%...
Change-Id: I3eb2f0401c39a5bdb5d1d8176e95df07be4c111a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166455
Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
Tested-by: Jenkins
Diffstat (limited to 'svl')
-rw-r--r-- | svl/source/items/itemset.cxx | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/svl/source/items/itemset.cxx b/svl/source/items/itemset.cxx index 61125a351a3d..4b1207a697aa 100644 --- a/svl/source/items/itemset.cxx +++ b/svl/source/items/itemset.cxx @@ -49,9 +49,26 @@ size_t getUsedSfxItemSetCount() { return nUsedSfxItemSetCount; } size_t getAllocatedSfxPoolItemHolderCount() { return nAllocatedSfxPoolItemHolderCount; } size_t getUsedSfxPoolItemHolderCount() { return nUsedSfxPoolItemHolderCount; } +// <WhichID, <number of entries, typeid_name>> typedef std::unordered_map<sal_uInt16, std::pair<sal_uInt32, const char*>> HightestUsage; static HightestUsage aHightestUsage; +// <TotalCount, <number of entries, sum of used count>> +typedef std::unordered_map<sal_uInt16, std::pair<sal_uInt32, sal_uInt32>> ItemArrayUsage; +static ItemArrayUsage aItemArrayUsage; + +static void addArrayUsage(sal_uInt16 nCount, sal_uInt16 nTotalCount) +{ + ItemArrayUsage::iterator aHit(aItemArrayUsage.find(nTotalCount)); + if (aHit == aItemArrayUsage.end()) + { + aItemArrayUsage.insert({nTotalCount, {1, nCount}}); + return; + } + aHit->second.first++; + aHit->second.second += nCount; +} + static void addUsage(const SfxPoolItem& rCandidate) { HightestUsage::iterator aHit(aHightestUsage.find(rCandidate.Which())); @@ -87,6 +104,42 @@ void listSfxPoolItemsWithHighestUsage(sal_uInt16 nNum) break; } } + +SVL_DLLPUBLIC void listSfxItemSetUsage() +{ + struct sorted { + sal_uInt16 nTotalCount; + sal_uInt32 nAppearances; + sal_uInt32 nAllUsedCount; + sorted(sal_uInt16 _nTotalCount, sal_uInt32 _nAppearances, sal_uInt32 _nAllUsedCount) + : nTotalCount(_nTotalCount), nAppearances(_nAppearances), nAllUsedCount(_nAllUsedCount) {} + bool operator<(const sorted& rDesc) const { return nTotalCount > rDesc.nTotalCount; } + }; + std::vector<sorted> aSorted; + aSorted.reserve(aItemArrayUsage.size()); + for (const auto& rEntry : aItemArrayUsage) + aSorted.emplace_back(rEntry.first, rEntry.second.first, rEntry.second.second); + std::sort(aSorted.begin(), aSorted.end()); + SAL_INFO("svl.items", "ITEM: List of " << aItemArrayUsage.size() << " SfxItemPool TotalCounts with usages:"); + double fAllFillRatePercent(0.0); + sal_uInt32 nUsed(0); + sal_uInt32 nAllocated(0); + for (const auto& rEntry : aSorted) + { + const sal_uInt32 nAllCount(rEntry.nAppearances * rEntry.nTotalCount); + const double fFillRatePercent(0 == nAllCount ? 0.0 : (static_cast<double>(rEntry.nAllUsedCount) / static_cast<double>(nAllCount)) * 100.0); + SAL_INFO("svl.items", + " TotalCount: " << rEntry.nTotalCount + << " Appearances: " << rEntry.nAppearances + << " FillRate(%): " << fFillRatePercent); + fAllFillRatePercent += fFillRatePercent; + nUsed += rEntry.nAllUsedCount; + nAllocated += rEntry.nTotalCount * rEntry.nAppearances; + } + SAL_INFO("svl.items", " Average FillRate(%): " << fAllFillRatePercent / aItemArrayUsage.size()); + SAL_INFO("svl.items", " Used: " << nUsed << " Allocated: " << nAllocated); + SAL_INFO("svl.items", " Average Used/Allocated(%): " << (static_cast<double>(nUsed) / static_cast<double>(nAllocated)) * 100.0); +} #endif // NOTE: Only needed for one Item in SC (see notes below for // ScPatternAttr). Still keep it so that when errors @@ -826,6 +879,7 @@ SfxItemSet::~SfxItemSet() { #ifdef DBG_UTIL nAllocatedSfxItemSetCount--; + addArrayUsage(Count(), TotalCount()); #endif // cleanup items. No std::fill needed, we are done with this ItemSet. // the callback is not set in destructor, so no worries about that |