sc/source/ui/inc/output.hxx | 1 + sc/source/ui/view/output2.cxx | 25 +++++++++++++++---------- 2 files changed, 16 insertions(+), 10 deletions(-)
New commits: commit d814d5610118cd4aed49f486295b449d2a75ae30 Author: Noel Grandin <noelgran...@gmail.com> AuthorDate: Sat Jul 26 13:56:41 2025 +0200 Commit: Noel Grandin <noelgran...@gmail.com> CommitDate: Sun Jul 27 21:37:28 2025 +0200 cool#11336 reduce cost of IsEmptyCellText (2) if we have to produce output data for a large range, we end up with an O(n^2) loop because we loop over X, while looping over X Change-Id: Ia16f635257e2547731e3343026c52cb6e8712d81 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/188400 Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> Tested-by: Jenkins diff --git a/sc/source/ui/inc/output.hxx b/sc/source/ui/inc/output.hxx index f120c2d66253..8c805ea09a92 100644 --- a/sc/source/ui/inc/output.hxx +++ b/sc/source/ui/inc/output.hxx @@ -316,6 +316,7 @@ private: /// inner loop of LayoutStrings void LayoutStringsImpl(bool bPixelToLogic, RowInfo* pThisRowInfo, SCCOL nX, SCROW nY, SCSIZE nArrY, std::optional<SCCOL>& oFirstNonEmptyCellX, + std::optional<SCCOL>& oLastEmptyCellX, SCCOL nLastContentCol, std::vector<std::unique_ptr<ScPatternAttr> >& aAltPatterns, const ScPatternAttr*& pOldPattern, diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx index 470d2f4c3de5..64c9e9b5c1d4 100644 --- a/sc/source/ui/view/output2.cxx +++ b/sc/source/ui/view/output2.cxx @@ -1559,9 +1559,10 @@ void ScOutputData::LayoutStrings(bool bPixelToLogic) if ( nLoopStartX < mnX1 ) nPosX -= mpRowInfo[0].basicCellInfo(nLoopStartX).nWidth * nLayoutSign; std::optional<SCCOL> oFirstNonEmptyCellX; + std::optional<SCCOL> oLastEmptyCellX; for (SCCOL nX=nLoopStartX; nX<=mnX2; nX++) { - LayoutStringsImpl(bPixelToLogic, pThisRowInfo, nX, nY, nArrY, oFirstNonEmptyCellX, nLastContentCol, + LayoutStringsImpl(bPixelToLogic, pThisRowInfo, nX, nY, nArrY, oFirstNonEmptyCellX, oLastEmptyCellX, nLastContentCol, aAltPatterns, pOldPattern, pOldCondSet, nOldScript, aVars, bProgress, nPosX, nPosY, bTaggedPDF, bReopenRowTag, pPDF, nLayoutSign, aDX); nPosX += mpRowInfo[0].basicCellInfo(nX).nWidth * nLayoutSign; @@ -1580,6 +1581,7 @@ void ScOutputData::LayoutStrings(bool bPixelToLogic) void ScOutputData::LayoutStringsImpl(bool const bPixelToLogic, RowInfo* const pThisRowInfo, SCCOL const nX, SCROW const nY, SCSIZE const nArrY, std::optional<SCCOL>& oFirstNonEmptyCellX, + std::optional<SCCOL>& oLastEmptyCellX, SCCOL const nLastContentCol, std::vector<std::unique_ptr<ScPatternAttr> >& aAltPatterns, const ScPatternAttr*& pOldPattern, @@ -1649,17 +1651,20 @@ void ScOutputData::LayoutStringsImpl(bool const bPixelToLogic, RowInfo* const pT if ( bEmpty && !bMergeEmpty && nX == mnX2 && !bOverlapped ) { - // don't have to look further than nLastContentCol - - SCCOL nTempX=nX; - while (nTempX < nLastContentCol && IsEmptyCellText( pThisRowInfo, nTempX, nY )) - ++nTempX; + if (!oLastEmptyCellX) + { + // don't have to look further than nLastContentCol + SCCOL nTempX=nX; + while (nTempX < nLastContentCol && IsEmptyCellText( pThisRowInfo, nTempX, nY )) + ++nTempX; + oLastEmptyCellX = nTempX; + } - if ( nTempX > nX && - !IsEmptyCellText( pThisRowInfo, nTempX, nY ) && - !mpDoc->HasAttrib( nTempX,nY,mnTab, nX,nY,mnTab, HasAttrFlags::Merged | HasAttrFlags::Overlapped ) ) + if ( *oLastEmptyCellX > nX && + !IsEmptyCellText( pThisRowInfo, *oLastEmptyCellX, nY ) && + !mpDoc->HasAttrib( *oLastEmptyCellX, nY,mnTab, nX,nY,mnTab, HasAttrFlags::Merged | HasAttrFlags::Overlapped ) ) { - nCellX = nTempX; + nCellX = *oLastEmptyCellX; bDoCell = true; } }