summaryrefslogtreecommitdiff
path: root/svl
diff options
context:
space:
mode:
authorArmin Le Grand (allotropia) <armin.le.grand.extern@allotropia.de>2024-04-22 15:16:42 +0200
committerArmin Le Grand <Armin.Le.Grand@me.com>2024-04-23 09:39:47 +0200
commitfd2aaac24712550e4bbd349575192edb56bc94c9 (patch)
tree79616409ba266e8589e7af093a27f5a286693dae /svl
parenta29d91ac403f1ed431ca95b8b9c290bd354c3ae7 (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.cxx54
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