sc/inc/fillinfo.hxx              |   22 +++++++++++++++++++---
 sc/source/core/data/fillinfo.cxx |   11 +++++++----
 sc/source/ui/view/output.cxx     |   12 ++++++------
 3 files changed, 32 insertions(+), 13 deletions(-)

New commits:
commit 73cfd7eeac7031c97a57bba82677f36ef1eff731
Author:     Luboš Luňák <l.lu...@collabora.com>
AuthorDate: Tue Feb 8 20:54:16 2022 +0100
Commit:     Luboš Luňák <l.lu...@collabora.com>
CommitDate: Thu Feb 10 09:39:13 2022 +0100

    avoid destructing many unique_ptr's most of which are nullptr
    
    With huge sheets there are so many CellInfo structures that
    calling all the destructors actually shows up in profiler data
    while trying to scroll around (it allocates CellInfo for every
    column starting from 0 up to the last one wanted). Keep
    the owning pointers in a vector that'll be much faster to process.
    
    Change-Id: Ibadb05fcce467fb808c38e2ed9a13b4cfef3720e
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129699
    Tested-by: Jenkins
    Reviewed-by: Luboš Luňák <l.lu...@collabora.com>

diff --git a/sc/inc/fillinfo.hxx b/sc/inc/fillinfo.hxx
index e5926808bf60..0bc72e4e3ed3 100644
--- a/sc/inc/fillinfo.hxx
+++ b/sc/inc/fillinfo.hxx
@@ -101,6 +101,8 @@ struct CellInfo
     CellInfo()
         : pPatternAttr(nullptr)
         , pConditionSet(nullptr)
+        , pDataBar(nullptr)
+        , pIconSet(nullptr)
         , pBackground(nullptr)   // TODO: omit?
         , pLinesAttr(nullptr)
         , mpTLBRLine(nullptr)
@@ -134,9 +136,9 @@ struct CellInfo
 
     const ScPatternAttr*        pPatternAttr;
     const SfxItemSet*           pConditionSet;
-    std::optional<Color>      mxColorScale;
-    std::unique_ptr<const ScDataBarInfo> pDataBar;
-    std::unique_ptr<const ScIconSetInfo> pIconSet;
+    std::optional<Color>        mxColorScale;
+    const ScDataBarInfo*        pDataBar;
+    const ScIconSetInfo*        pIconSet;
 
     const SvxBrushItem*         pBackground;
 
@@ -229,6 +231,20 @@ struct ScTableInfo
                         ~ScTableInfo();
     ScTableInfo(const ScTableInfo&) = delete;
     const ScTableInfo& operator=(const ScTableInfo&) = delete;
+
+    void addDataBarInfo(std::unique_ptr<const ScDataBarInfo> info)
+    {
+        mDataBarInfos.push_back(std::move(info));
+    }
+    void addIconSetInfo(std::unique_ptr<const ScIconSetInfo> info)
+    {
+        mIconSetInfos.push_back(std::move(info));
+    }
+private:
+    // These are owned here and not in CellInfo to avoid freeing
+    // memory for every pointer in CellInfo, most of which are nullptr.
+    std::vector<std::unique_ptr<const ScDataBarInfo>> mDataBarInfos;
+    std::vector<std::unique_ptr<const ScIconSetInfo>> mIconSetInfos;
 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/fillinfo.cxx b/sc/source/core/data/fillinfo.cxx
index 1dca158f1e28..db18514b7120 100644
--- a/sc/source/core/data/fillinfo.cxx
+++ b/sc/source/core/data/fillinfo.cxx
@@ -276,7 +276,7 @@ void initColWidths(RowInfo* pRowInfo, const ScDocument* 
pDoc, double fColScale,
 }
 
 bool handleConditionalFormat(ScConditionalFormatList& rCondFormList, const 
ScCondFormatIndexes& rCondFormats,
-        CellInfo* pInfo, ScStyleSheetPool* pStlPool,
+        CellInfo* pInfo, ScTableInfo* pTableInfo, ScStyleSheetPool* pStlPool,
         const ScAddress& rAddr, bool& bHidden, bool& bHideFormula, bool 
bTabProtect)
 {
     bool bFound = false;
@@ -324,13 +324,15 @@ bool handleConditionalFormat(ScConditionalFormatList& 
rCondFormList, const ScCon
 
         if(aData.pDataBar)
         {
-            pInfo->pDataBar = std::move(aData.pDataBar);
+            pInfo->pDataBar = aData.pDataBar.get();
+            pTableInfo->addDataBarInfo(std::move(aData.pDataBar));
             bFound = true;
         }
 
         if(aData.pIconSet)
         {
-            pInfo->pIconSet = std::move(aData.pIconSet);
+            pInfo->pIconSet = aData.pIconSet.get();
+            pTableInfo->addIconSetInfo(std::move(aData.pIconSet));
             bFound = true;
         }
 
@@ -552,7 +554,8 @@ void ScDocument::FillInfo(
 
                                 if (bContainsCondFormat && pCondFormList)
                                 {
-                                    bAnyCondition |= 
handleConditionalFormat(*pCondFormList, rCondFormats, pInfo, pStlPool, 
ScAddress(nCol, nCurRow, nTab),
+                                    bAnyCondition |= 
handleConditionalFormat(*pCondFormList, rCondFormats,
+                                            pInfo, &rTabInfo, pStlPool, 
ScAddress(nCol, nCurRow, nTab),
                                             bHidden, bHideFormula, 
bTabProtect);
                                 }
 
diff --git a/sc/source/ui/view/output.cxx b/sc/source/ui/view/output.cxx
index 776c164cd2d7..810b01812769 100644
--- a/sc/source/ui/view/output.cxx
+++ b/sc/source/ui/view/output.cxx
@@ -789,8 +789,8 @@ static bool lcl_EqualBack( const RowInfo& rFirst, const 
RowInfo& rOther,
         if (pCol1 && (*pCol1 != *pCol2))
             return false;
 
-        const ScDataBarInfo* pInfo1 = rFirst.cellInfo(nX).pDataBar.get();
-        const ScDataBarInfo* pInfo2 = rOther.cellInfo(nX).pDataBar.get();
+        const ScDataBarInfo* pInfo1 = rFirst.cellInfo(nX).pDataBar;
+        const ScDataBarInfo* pInfo2 = rOther.cellInfo(nX).pDataBar;
 
         if( (pInfo1 && !pInfo2) || (!pInfo1 && pInfo2) )
             return false;
@@ -799,8 +799,8 @@ static bool lcl_EqualBack( const RowInfo& rFirst, const 
RowInfo& rOther,
             return false;
 
         // each cell with an icon set should be painted the same way
-        const ScIconSetInfo* pIconSet1 = rFirst.cellInfo(nX).pIconSet.get();
-        const ScIconSetInfo* pIconSet2 = rOther.cellInfo(nX).pIconSet.get();
+        const ScIconSetInfo* pIconSet1 = rFirst.cellInfo(nX).pIconSet;
+        const ScIconSetInfo* pIconSet2 = rOther.cellInfo(nX).pIconSet;
 
         if(pIconSet1 || pIconSet2)
             return false;
@@ -1133,8 +1133,8 @@ void ScOutputData::DrawBackground(vcl::RenderContext& 
rRenderContext)
                     }
 
                     std::optional<Color> const & pColor = pInfo->mxColorScale;
-                    const ScDataBarInfo* pDataBarInfo = pInfo->pDataBar.get();
-                    const ScIconSetInfo* pIconSetInfo = pInfo->pIconSet.get();
+                    const ScDataBarInfo* pDataBarInfo = pInfo->pDataBar;
+                    const ScIconSetInfo* pIconSetInfo = pInfo->pIconSet;
 
                     tools::Long nPosXLogic = nPosX;
                     if (bWorksInPixels)

Reply via email to