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.grandin@collabora.co.uk>
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
diff --git a/editeng/source/editeng/editobj.cxx b/editeng/source/editeng/editobj.cxx
index 762cac1..9b17e43 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 fd1f143..4392022b 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 8346f43..0a17cd6 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 5badaf8..b78b1a91 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 65facba..8abe7dc 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 a790172..1c82cfa 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 21c2a9c..e4153cb 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 ffe081e..76f9310 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 4957a4f..6b39887 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( !pOPO )
return false;
if( nParaCount > 0 )
bHasText = (nParaCount > 1) || (!rETO.GetText( 0 ).isEmpty());
}
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 a7dc739..0c4c4ba 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 714c141..409b8be 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("...");