editeng/source/editeng/editobj.cxx                  |   14 ++++++++++++++
 editeng/source/editeng/editobj2.hxx                 |    2 ++
 editeng/source/outliner/overflowingtxt.cxx          |    2 +-
 include/editeng/editobj.hxx                         |    4 ++++
 sc/source/filter/xcl97/xcl97rec.cxx                 |    3 +--
 sc/source/ui/Accessibility/AccessiblePageHeader.cxx |    2 +-
 sc/source/ui/view/viewfunc.cxx                      |    2 +-
 sd/source/filter/ppt/pptinanimations.cxx            |    2 +-
 svx/source/svdraw/svdotxat.cxx                      |   19 +++++++++----------
 svx/source/table/cell.cxx                           |    2 +-
 sw/source/uibase/docvw/AnnotationWin.cxx            |    2 +-
 11 files changed, 36 insertions(+), 18 deletions(-)

New commits:
commit 6f8073caf0d6b331232f6edb5f18d14ddefdb465
Author:     Noel Grandin <noel.gran...@collabora.co.uk>
AuthorDate: Wed Mar 6 09:43:28 2024 +0200
Commit:     Noel Grandin <noel.gran...@collabora.co.uk>
CommitDate: Wed Mar 6 13:00:19 2024 +0100

    tdf#158773 reduce cost of ContentInfo::GetText
    
    The specific path that is showing up on the perf profile is
    
    SdrTextObj::HasText -> EditTextObjectImpl::GetText ->
    ContentInfo::GetText
    
    Reduce the cost by 10% there by adding a method to check if we have text, 
and
    avoid the cost of constructing an OUString from an svl::SharedString.
    
    Also make use of the new method in places.
    
    Change-Id: Ibc2e0f61c4a2a6c33eea7f2cce09d692d82fd2b2
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164449
    Tested-by: Noel Grandin <noel.gran...@collabora.co.uk>
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>

diff --git a/editeng/source/editeng/editobj.cxx 
b/editeng/source/editeng/editobj.cxx
index 762cac112ddb..9b17e434e53d 100644
--- a/editeng/source/editeng/editobj.cxx
+++ b/editeng/source/editeng/editobj.cxx
@@ -126,6 +126,12 @@ OUString ContentInfo::GetText() const
     return OUString(p);
 }
 
+sal_Int32 ContentInfo::GetTextLen() const
+{
+    const rtl_uString* p = maText.getData();
+    return p->length;
+}
+
 void ContentInfo::SetText( const OUString& rStr )
 {
     maText = svl::SharedString(rStr.pData, nullptr);
@@ -392,6 +398,14 @@ OUString EditTextObjectImpl::GetText(sal_Int32 nPara) const
     return maContents[nPara]->GetText();
 }
 
+sal_Int32 EditTextObjectImpl::GetTextLen(sal_Int32 nPara ) const
+{
+    if (nPara < 0 || o3tl::make_unsigned(nPara) >= maContents.size())
+        return 0;
+
+    return maContents[nPara]->GetTextLen();
+}
+
 void EditTextObjectImpl::ClearPortionInfo()
 {
     mpPortionInfo.reset();
diff --git a/editeng/source/editeng/editobj2.hxx 
b/editeng/source/editeng/editobj2.hxx
index fd1f1437e910..4392022b77a3 100644
--- a/editeng/source/editeng/editobj2.hxx
+++ b/editeng/source/editeng/editobj2.hxx
@@ -140,6 +140,7 @@ public:
     const svl::SharedString& GetSharedString() const { return maText;}
     OUString GetText() const;
     void SetText( const OUString& rStr );
+    sal_Int32 GetTextLen() const;
 
     void dumpAsXml(xmlTextWriterPtr pWriter) const;
 
@@ -225,6 +226,7 @@ public:
 
     virtual sal_Int32 GetParagraphCount() const override;
     virtual OUString GetText(sal_Int32 nParagraph) const override;
+    virtual sal_Int32 GetTextLen(sal_Int32 nParagraph) const override;
 
     virtual void ClearPortionInfo() override;
 
diff --git a/editeng/source/outliner/overflowingtxt.cxx 
b/editeng/source/outliner/overflowingtxt.cxx
index 8346f432b41b..0a17cd609100 100644
--- a/editeng/source/outliner/overflowingtxt.cxx
+++ b/editeng/source/outliner/overflowingtxt.cxx
@@ -45,7 +45,7 @@ std::optional<OutlinerParaObject> 
TextChainingUtils::JuxtaposeParaObject(
     // Special case: if only empty text remove it at the end
     bool bOnlyOneEmptyPara = !pNextPObj ||
                              (pOutl->GetParagraphCount() == 1 &&
-                              pNextPObj->GetTextObject().GetText(0).isEmpty());
+                              !pNextPObj->GetTextObject().HasText(0));
 
     EditEngine &rEditEngine = const_cast<EditEngine &>(pOutl->GetEditEngine());
 
diff --git a/include/editeng/editobj.hxx b/include/editeng/editobj.hxx
index 5badaf8e8a2a..b78b1a918b27 100644
--- a/include/editeng/editobj.hxx
+++ b/include/editeng/editobj.hxx
@@ -87,6 +87,10 @@ public:
 
     virtual OUString GetText(sal_Int32 nPara) const = 0;
 
+    virtual sal_Int32 GetTextLen(sal_Int32 nPara) const = 0;
+
+    bool HasText(sal_Int32 nPara) const { return GetTextLen(nPara) > 0; }
+
     virtual void ClearPortionInfo() = 0;
 
     virtual bool HasOnlineSpellErrors() const = 0;
diff --git a/sc/source/filter/xcl97/xcl97rec.cxx 
b/sc/source/filter/xcl97/xcl97rec.cxx
index 65facba4b739..8abe7dc68372 100644
--- a/sc/source/filter/xcl97/xcl97rec.cxx
+++ b/sc/source/filter/xcl97/xcl97rec.cxx
@@ -921,8 +921,7 @@ XclTxo::XclTxo( const XclExpRoot& rRoot, const 
EditTextObject& rEditObj, SdrObje
     // Excel has one alignment per NoteObject while Calc supports
     // one alignment per paragraph - use the first paragraph
     // alignment (if set) as our overall alignment.
-    OUString aParaText( rEditObj.GetText( 0 ) );
-    if( !aParaText.isEmpty() )
+    if( rEditObj.HasText( 0 ) )
     {
         const SfxItemSet& aSet( rEditObj.GetParaAttribs( 0));
         if( const SvxAdjustItem* pItem = aSet.GetItemIfSet( EE_PARA_JUST ) )
diff --git a/sc/source/ui/Accessibility/AccessiblePageHeader.cxx 
b/sc/source/ui/Accessibility/AccessiblePageHeader.cxx
index a79017276b36..1c82cfac7542 100644
--- a/sc/source/ui/Accessibility/AccessiblePageHeader.cxx
+++ b/sc/source/ui/Accessibility/AccessiblePageHeader.cxx
@@ -348,7 +348,7 @@ bool ScAccessiblePageHeader::IsDefunc( sal_Int64 
nParentStates )
 
 void ScAccessiblePageHeader::AddChild(const EditTextObject* pArea, sal_uInt32 
nIndex, SvxAdjust eAdjust)
 {
-    if (pArea && (!pArea->GetText(0).isEmpty() || (pArea->GetParagraphCount() 
> 1)))
+    if (pArea && ((pArea->GetParagraphCount() > 1) || pArea->HasText(0)))
     {
         if (maAreas[nIndex].is())
         {
diff --git a/sc/source/ui/view/viewfunc.cxx b/sc/source/ui/view/viewfunc.cxx
index 21c2a9c3d44f..e4153cb0d826 100644
--- a/sc/source/ui/view/viewfunc.cxx
+++ b/sc/source/ui/view/viewfunc.cxx
@@ -921,7 +921,7 @@ void ScViewFunc::EnterData( SCCOL nCol, SCROW nRow, SCTAB 
nTab,
             pDocSh->UpdateOle(GetViewData());
 
             bool bIsEmpty = rData.GetParagraphCount() == 0
-                || (rData.GetParagraphCount() == 1 && 
rData.GetText(0).isEmpty());
+                || (rData.GetParagraphCount() == 1 && !rData.HasText(0));
             const OUString aType(bIsEmpty ? u"delete-content" : 
u"cell-change");
             HelperNotifyChanges::NotifyIfChangesListeners(*pDocSh, rMark, 
nCol, nRow, aType);
 
diff --git a/sd/source/filter/ppt/pptinanimations.cxx 
b/sd/source/filter/ppt/pptinanimations.cxx
index ffe081ed1217..76f9310da1bc 100644
--- a/sd/source/filter/ppt/pptinanimations.cxx
+++ b/sd/source/filter/ppt/pptinanimations.cxx
@@ -2523,7 +2523,7 @@ void AnimationImporter::importTargetElementContainer( 
const Atom* pAtom, Any& rT
 
                     while( (nPara < nParaCount) && (begin > 0) )
                     {
-                        sal_Int32 nParaLength = rEditTextObject.GetText( nPara 
).getLength() + 1;
+                        sal_Int32 nParaLength = rEditTextObject.GetTextLen( 
nPara ) + 1;
                         begin -= nParaLength;
                         end -= nParaLength;
                         nPara++;
diff --git a/svx/source/svdraw/svdotxat.cxx b/svx/source/svdraw/svdotxat.cxx
index 4957a4fe9806..6b39887d17f9 100644
--- a/svx/source/svdraw/svdotxat.cxx
+++ b/svx/source/svdraw/svdotxat.cxx
@@ -424,17 +424,16 @@ bool SdrTextObj::HasText() const
 
     OutlinerParaObject* pOPO = GetOutlinerParaObject();
 
-    bool bHasText = false;
-    if( pOPO )
-    {
-        const EditTextObject& rETO = pOPO->GetTextObject();
-        sal_Int32 nParaCount = rETO.GetParagraphCount();
-
-        if( nParaCount > 0 )
-            bHasText = (nParaCount > 1) || (!rETO.GetText( 0 ).isEmpty());
-    }
+    if( !pOPO )
+        return false;
 
-    return bHasText;
+    const EditTextObject& rETO = pOPO->GetTextObject();
+    sal_Int32 nParaCount = rETO.GetParagraphCount();
+    if( nParaCount == 0 )
+        return false;
+    if( nParaCount > 1 )
+        return true;
+    return rETO.HasText( 0 );
 }
 
 void SdrTextObj::AppendFamilyToStyleName(OUString& styleName, SfxStyleFamily 
family)
diff --git a/svx/source/table/cell.cxx b/svx/source/table/cell.cxx
index a7dc7397e9ad..0c4c4baa5dfb 100644
--- a/svx/source/table/cell.cxx
+++ b/svx/source/table/cell.cxx
@@ -563,7 +563,7 @@ bool Cell::hasText() const
         {
             if( rTextObj.GetParagraphCount() == 1 )
             {
-                if( rTextObj.GetText(0).isEmpty() )
+                if( !rTextObj.HasText(0) )
                     return false;
             }
             return true;
diff --git a/sw/source/uibase/docvw/AnnotationWin.cxx 
b/sw/source/uibase/docvw/AnnotationWin.cxx
index 714c1419d2ed..409b8be9a7a7 100644
--- a/sw/source/uibase/docvw/AnnotationWin.cxx
+++ b/sw/source/uibase/docvw/AnnotationWin.cxx
@@ -417,7 +417,7 @@ void SwAnnotationWin::InitAnswer(OutlinerParaObject const & 
rText)
 
     // insert old, selected text or "..."
     // TODO: iterate over all paragraphs, not only first one to find out if it 
is empty
-    if (!rText.GetTextObject().GetText(0).isEmpty())
+    if (rText.GetTextObject().HasText(0))
         GetOutlinerView()->GetEditView().InsertText(rText.GetTextObject());
     else
         GetOutlinerView()->InsertText("...");

Reply via email to