sw/inc/swcrsr.hxx | 4 +++- sw/source/core/crsr/findattr.cxx | 9 ++++++--- sw/source/core/crsr/findcoll.cxx | 5 +++-- sw/source/core/crsr/findtxt.cxx | 24 +++++++++++++++--------- sw/source/core/crsr/swcrsr.cxx | 7 +++++-- sw/source/core/inc/pamtyp.hxx | 4 +++- 6 files changed, 35 insertions(+), 18 deletions(-)
New commits: commit 1159f58831c69680e9f10767d5358e13b66579dd Author: Noel Grandin <noel.gran...@collabora.co.uk> AuthorDate: Tue Sep 8 11:51:59 2020 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Wed Sep 9 08:25:01 2020 +0200 tdf#119286 speed up find/replace SvxSearchItem is very expensive to construct, so move it outside the primary loop. This takes the time from 6s to 3s for me. Change-Id: Ie6491761e69c4f787910d7ecfbd071b7e68efd35 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102231 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> diff --git a/sw/inc/swcrsr.hxx b/sw/inc/swcrsr.hxx index 923928887023..a6e634ac3b55 100644 --- a/sw/inc/swcrsr.hxx +++ b/sw/inc/swcrsr.hxx @@ -25,6 +25,7 @@ class SfxItemSet; struct SwCursor_SavePos; +class SvxSearchItem; namespace i18nutil { struct SearchOptions2; } @@ -37,7 +38,8 @@ const int FIND_NO_RING = 2; struct SwFindParas { - virtual int DoFind(SwPaM &, SwMoveFnCollection const &, const SwPaM&, bool) = 0; + // @param xSearchItem allocate in parent so we can do so outside the calling loop + virtual int DoFind(SwPaM &, SwMoveFnCollection const &, const SwPaM&, bool, std::unique_ptr<SvxSearchItem>& xSearchItem) = 0; virtual bool IsReplaceMode() const = 0; protected: diff --git a/sw/source/core/crsr/findattr.cxx b/sw/source/core/crsr/findattr.cxx index 40d536de3083..8d1cafd41c64 100644 --- a/sw/source/core/crsr/findattr.cxx +++ b/sw/source/core/crsr/findattr.cxx @@ -25,6 +25,7 @@ #include <unotools/syslocale.hxx> #include <hintids.hxx> #include <svl/itemiter.hxx> +#include <svl/srchitem.hxx> #include <svl/whiter.hxx> #include <editeng/colritem.hxx> #include <editeng/fontitem.hxx> @@ -1253,14 +1254,16 @@ struct SwFindParaAttr : public SwFindParas virtual ~SwFindParaAttr() {} - virtual int DoFind(SwPaM &, SwMoveFnCollection const &, const SwPaM &, bool bInReadOnly) override; + virtual int DoFind(SwPaM &, SwMoveFnCollection const &, const SwPaM &, bool bInReadOnly, + std::unique_ptr<SvxSearchItem>& xSearchItem) override; virtual bool IsReplaceMode() const override; }; } int SwFindParaAttr::DoFind(SwPaM & rCursor, SwMoveFnCollection const & fnMove, - const SwPaM & rRegion, bool bInReadOnly) + const SwPaM & rRegion, bool bInReadOnly, + std::unique_ptr<SvxSearchItem>& xSearchItem) { // replace string (only if text given and search is not parameterized)? bool bReplaceText = pSearchOpt && ( !pSearchOpt->replaceString.isEmpty() || @@ -1310,7 +1313,7 @@ int SwFindParaAttr::DoFind(SwPaM & rCursor, SwMoveFnCollection const & fnMove, // TODO: searching for attributes in Outliner text?! // continue search in correct section (pTextRegion) - if (sw::FindTextImpl(aSrchPam, *pSearchOpt, false/*bSearchInNotes*/, *pSText, fnMove, *pTextRegion, bInReadOnly, m_pLayout) && + if (sw::FindTextImpl(aSrchPam, *pSearchOpt, false/*bSearchInNotes*/, *pSText, fnMove, *pTextRegion, bInReadOnly, m_pLayout, xSearchItem) && *aSrchPam.GetMark() != *aSrchPam.GetPoint() ) break; // found else if( !pSet->Count() ) diff --git a/sw/source/core/crsr/findcoll.cxx b/sw/source/core/crsr/findcoll.cxx index f80fff2c10ee..8385e0a4cf24 100644 --- a/sw/source/core/crsr/findcoll.cxx +++ b/sw/source/core/crsr/findcoll.cxx @@ -41,14 +41,15 @@ struct SwFindParaFormatColl : public SwFindParas , m_pLayout(pLayout) {} virtual ~SwFindParaFormatColl() {} - virtual int DoFind(SwPaM &, SwMoveFnCollection const &, const SwPaM &, bool bInReadOnly) override; + virtual int DoFind(SwPaM &, SwMoveFnCollection const &, const SwPaM &, bool bInReadOnly, std::unique_ptr<SvxSearchItem>& xSearchItem) override; virtual bool IsReplaceMode() const override; }; } int SwFindParaFormatColl::DoFind(SwPaM & rCursor, SwMoveFnCollection const & fnMove, - const SwPaM & rRegion, bool bInReadOnly) + const SwPaM & rRegion, bool bInReadOnly, + std::unique_ptr<SvxSearchItem>& /*xSearchItem*/) { int nRet = FIND_FOUND; if( bInReadOnly && pReplColl ) diff --git a/sw/source/core/crsr/findtxt.cxx b/sw/source/core/crsr/findtxt.cxx index b7c4afbf1e47..1e9ecef2c2d2 100644 --- a/sw/source/core/crsr/findtxt.cxx +++ b/sw/source/core/crsr/findtxt.cxx @@ -369,11 +369,13 @@ static bool DoSearch(SwPaM & rSearchPam, namespace sw { +// @param xSearchItem allocate in parent so we can do so outside the calling loop bool FindTextImpl(SwPaM & rSearchPam, const i18nutil::SearchOptions2& rSearchOpt, bool bSearchInNotes, utl::TextSearch& rSText, SwMoveFnCollection const & fnMove, const SwPaM & rRegion, - bool bInReadOnly, SwRootFrame const*const pLayout) + bool bInReadOnly, SwRootFrame const*const pLayout, + std::unique_ptr<SvxSearchItem>& xSearchItem) { if( rSearchOpt.searchString.isEmpty() ) return false; @@ -395,9 +397,12 @@ bool FindTextImpl(SwPaM & rSearchPam, rSearchOpt.searchString == "$^" ); const bool bChkParaEnd = bRegSearch && rSearchOpt.searchString == "$"; - SvxSearchItem aSearchItem(SID_SEARCH_ITEM); // this is a very expensive operation (calling configmgr etc.) - aSearchItem.SetSearchOptions(rSearchOpt); - aSearchItem.SetBackward(!bSrchForward); + if (!xSearchItem) + { + xSearchItem.reset(new SvxSearchItem(SID_SEARCH_ITEM)); // this is a very expensive operation (calling configmgr etc.) + xSearchItem->SetSearchOptions(rSearchOpt); + xSearchItem->SetBackward(!bSrchForward); + } // LanguageType eLastLang = 0; while (nullptr != (pNode = ::GetNode(*pPam, bFirst, fnMove, bInReadOnly, pLayout))) @@ -525,7 +530,7 @@ bool FindTextImpl(SwPaM & rSearchPam, if (pObject) { - sal_uInt16 nResult = pSdrView->GetTextEditOutlinerView()->StartSearchAndReplace(aSearchItem); + sal_uInt16 nResult = pSdrView->GetTextEditOutlinerView()->StartSearchAndReplace(*xSearchItem); if (!nResult) { // If not found, end the text edit. @@ -577,7 +582,7 @@ bool FindTextImpl(SwPaM & rSearchPam, aPaM.GetMark()->nNode = rTextNode.GetIndex() + 1; } aPaM.GetMark()->nContent.Assign(aPaM.GetMark()->nNode.GetNode().GetTextNode(), 0); - if (pNode->GetDoc()->getIDocumentDrawModelAccess().Search(aPaM, aSearchItem) && pSdrView) + if (pNode->GetDoc()->getIDocumentDrawModelAccess().Search(aPaM, *xSearchItem) && pSdrView) { if (SdrObject* pObject = pSdrView->GetTextEditObject()) { @@ -931,7 +936,7 @@ struct SwFindParaText : public SwFindParas , m_bReplace( bRepl ) , m_bSearchInNotes( bSearchInNotes ) {} - virtual int DoFind(SwPaM &, SwMoveFnCollection const &, const SwPaM &, bool bInReadOnly) override; + virtual int DoFind(SwPaM &, SwMoveFnCollection const &, const SwPaM &, bool bInReadOnly, std::unique_ptr<SvxSearchItem>& xSearchItem) override; virtual bool IsReplaceMode() const override; virtual ~SwFindParaText(); }; @@ -943,13 +948,14 @@ SwFindParaText::~SwFindParaText() } int SwFindParaText::DoFind(SwPaM & rCursor, SwMoveFnCollection const & fnMove, - const SwPaM & rRegion, bool bInReadOnly) + const SwPaM & rRegion, bool bInReadOnly, + std::unique_ptr<SvxSearchItem>& xSearchItem) { if( bInReadOnly && m_bReplace ) bInReadOnly = false; const bool bFnd = sw::FindTextImpl(rCursor, m_rSearchOpt, m_bSearchInNotes, - m_aSText, fnMove, rRegion, bInReadOnly, m_pLayout); + m_aSText, fnMove, rRegion, bInReadOnly, m_pLayout, xSearchItem); if( bFnd && m_bReplace ) // replace string { diff --git a/sw/source/core/crsr/swcrsr.cxx b/sw/source/core/crsr/swcrsr.cxx index a4b1d6a54c50..97e46bd827e9 100644 --- a/sw/source/core/crsr/swcrsr.cxx +++ b/sw/source/core/crsr/swcrsr.cxx @@ -23,6 +23,7 @@ #include <com/sun/star/i18n/XBreakIterator.hpp> #include <unotools/charclass.hxx> #include <svl/ctloptions.hxx> +#include <svl/srchitem.hxx> #include <swmodule.hxx> #include <fmtcntnt.hxx> #include <swtblfmt.hxx> @@ -768,6 +769,7 @@ static sal_uLong lcl_FindSelection( SwFindParas& rParas, SwCursor* pCurrentCurso sal_uLong nFound = 0; const bool bSrchBkwrd = &fnMove == &fnMoveBackward; SwPaM *pTmpCursor = pCurrentCursor, *pSaveCursor = pCurrentCursor; + std::unique_ptr<SvxSearchItem> xSearchItem; // only create progress bar for ShellCursor bool bIsUnoCursor = dynamic_cast<SwUnoCursor*>(pCurrentCursor) != nullptr; @@ -801,7 +803,7 @@ static sal_uLong lcl_FindSelection( SwFindParas& rParas, SwCursor* pCurrentCurso // as long as found and not at same position while( *pSttPos <= *pEndPos ) { - nFndRet = rParas.DoFind(*pCurrentCursor, fnMove, aRegion, bInReadOnly); + nFndRet = rParas.DoFind(*pCurrentCursor, fnMove, aRegion, bInReadOnly, xSearchItem); if( 0 == nFndRet || ( pFndRing && *pFndRing->GetPoint() == *pCurrentCursor->GetPoint() && @@ -961,6 +963,7 @@ sal_uLong SwCursor::FindAll( SwFindParas& rParas, sal_uLong nFound = 0; const bool bMvBkwrd = &fnMove == &fnMoveBackward; bool bInReadOnly = IsReadOnlyAvailable(); + std::unique_ptr<SvxSearchItem> xSearchItem; SwCursor* pFndRing = nullptr; SwNodes& rNds = GetDoc()->GetNodes(); @@ -1089,7 +1092,7 @@ sal_uLong SwCursor::FindAll( SwFindParas& rParas, SwPosition aMarkPos( *GetMark() ); const bool bMarkPos = HasMark() && (eFndRngs == FindRanges::InBody); - nFound = rParas.DoFind(*this, fnMove, aRegion, bInReadOnly) ? 1 : 0; + nFound = rParas.DoFind(*this, fnMove, aRegion, bInReadOnly, xSearchItem) ? 1 : 0; if (0 != nFound && bMarkPos) *GetMark() = aMarkPos; } diff --git a/sw/source/core/inc/pamtyp.hxx b/sw/source/core/inc/pamtyp.hxx index 9326b348dcc2..b1bb6c1f4722 100644 --- a/sw/source/core/inc/pamtyp.hxx +++ b/sw/source/core/inc/pamtyp.hxx @@ -36,6 +36,7 @@ class SwNode; class SwNodeIndex; class SwContentNode; class SwIndex; +class SvxSearchItem; namespace i18nutil { struct SearchOptions2; @@ -94,7 +95,8 @@ namespace sw { utl::TextSearch& rSText, SwMoveFnCollection const & fnMove, const SwPaM & rRegion, bool bInReadOnly, - SwRootFrame const* pLayout); + SwRootFrame const* pLayout, + std::unique_ptr<SvxSearchItem>& xSearchItem); bool FindFormatImpl(SwPaM & rSearchPam, const SwFormat& rFormat, SwMoveFnCollection const & fnMove, _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits