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)