summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2022-02-20 10:11:15 +0100
committerLuboš Luňák <l.lunak@collabora.com>2022-02-20 11:44:15 +0100
commit9c7f3ddf5b3c23de0fed08fa3ebdfa2a95fec588 (patch)
tree65d3b53be6f3577f36304e40fd0eacf4e55bd29b
parentmake CollectCellAction sort cells by cell address (tdf#119083) (diff)
downloadcore-9c7f3ddf5b3c23de0fed08fa3ebdfa2a95fec588.tar.gz
core-9c7f3ddf5b3c23de0fed08fa3ebdfa2a95fec588.zip
optimize XclExpRowBuffer::GetOrCreateRow() (tdf#140893)
This gets called often especially with larger spreadsheets. Change-Id: I6acf23d0942d1745a52963c9b5b08453e1ec28bc Reviewed-on: https://gerrit.libreoffice.org/c/core/+/130207 Tested-by: Jenkins Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
-rw-r--r--sc/source/filter/excel/xetable.cxx96
1 files changed, 55 insertions, 41 deletions
diff --git a/sc/source/filter/excel/xetable.cxx b/sc/source/filter/excel/xetable.cxx
index 2164adcfacea..6945e724d6ba 100644
--- a/sc/source/filter/excel/xetable.cxx
+++ b/sc/source/filter/excel/xetable.cxx
@@ -2426,53 +2426,67 @@ void XclExpRowBuffer::SaveXml( XclExpXmlStream& rStrm )
XclExpRow& XclExpRowBuffer::GetOrCreateRow( sal_uInt32 nXclRow, bool bRowAlwaysEmpty )
{
- RowMap::iterator itr = maRowMap.lower_bound( nXclRow );
+ // This is called rather often, so optimize for the most common case of saving row by row
+ // (so the requested row is often the last one in the map or belongs after the last one).
+ RowMap::iterator itr;
+ if(maRowMap.empty())
+ itr = maRowMap.end();
+ else
+ {
+ RowMap::reverse_iterator last = maRowMap.rbegin();
+ if( last->first == nXclRow )
+ return *last->second;
+ if( nXclRow > last->first )
+ itr = maRowMap.end();
+ else
+ itr = maRowMap.lower_bound( nXclRow );
+ }
const bool bFound = itr != maRowMap.end();
// bFoundHigher: nXclRow was identical to the previous entry, so not explicitly created earlier
- const bool bFoundHigher = bFound && itr != maRowMap.find( nXclRow );
- if( !bFound || bFoundHigher )
- {
- size_t nFrom = 0;
- RowRef pPrevEntry;
- if( itr != maRowMap.begin() )
- {
- --itr;
- pPrevEntry = itr->second;
- if( bFoundHigher )
- nFrom = nXclRow;
- else
- nFrom = itr->first + 1;
- }
-
- const ScDocument& rDoc = GetRoot().GetDoc();
- const SCTAB nScTab = GetRoot().GetCurrScTab();
- // create the missing rows first
- while( nFrom <= nXclRow )
+ const bool bFoundHigher = bFound && itr->first != nXclRow;
+ if( bFound && !bFoundHigher )
+ return *itr->second;
+
+ size_t nFrom = 0;
+ RowRef pPrevEntry;
+ if( itr != maRowMap.begin() )
+ {
+ --itr;
+ pPrevEntry = itr->second;
+ if( bFoundHigher )
+ nFrom = nXclRow;
+ else
+ nFrom = itr->first + 1;
+ }
+
+ const ScDocument& rDoc = GetRoot().GetDoc();
+ const SCTAB nScTab = GetRoot().GetCurrScTab();
+ // create the missing rows first
+ while( nFrom <= nXclRow )
+ {
+ // only create RowMap entries if it is first row in spreadsheet,
+ // if it is the desired row, or for rows that differ from previous.
+ const bool bHidden = rDoc.RowHidden(nFrom, nScTab);
+ // Always get the actual row height even if the manual size flag is
+ // not set, to correctly export the heights of rows with wrapped
+ // texts.
+ const sal_uInt16 nHeight = rDoc.GetRowHeight(nFrom, nScTab, false);
+ if ( !pPrevEntry || ( nFrom == nXclRow ) ||
+ ( maOutlineBfr.IsCollapsed() ) ||
+ ( maOutlineBfr.GetLevel() != 0 ) ||
+ ( bRowAlwaysEmpty && !pPrevEntry->IsEmpty() ) ||
+ ( bHidden != pPrevEntry->IsHidden() ) ||
+ ( nHeight != pPrevEntry->GetHeight() ) )
{
- // only create RowMap entries if it is first row in spreadsheet,
- // if it is the desired row, or for rows that differ from previous.
- const bool bHidden = rDoc.RowHidden(nFrom, nScTab);
- // Always get the actual row height even if the manual size flag is
- // not set, to correctly export the heights of rows with wrapped
- // texts.
- const sal_uInt16 nHeight = rDoc.GetRowHeight(nFrom, nScTab, false);
- if ( !pPrevEntry || ( nFrom == nXclRow ) ||
- ( maOutlineBfr.IsCollapsed() ) ||
- ( maOutlineBfr.GetLevel() != 0 ) ||
- ( bRowAlwaysEmpty && !pPrevEntry->IsEmpty() ) ||
- ( bHidden != pPrevEntry->IsHidden() ) ||
- ( nHeight != pPrevEntry->GetHeight() ) )
+ if( maOutlineBfr.GetLevel() > mnHighestOutlineLevel )
{
- if( maOutlineBfr.GetLevel() > mnHighestOutlineLevel )
- {
- mnHighestOutlineLevel = maOutlineBfr.GetLevel();
- }
- RowRef p = std::make_shared<XclExpRow>(GetRoot(), nFrom, maOutlineBfr, bRowAlwaysEmpty, bHidden, nHeight);
- maRowMap.emplace(nFrom, p);
- pPrevEntry = p;
+ mnHighestOutlineLevel = maOutlineBfr.GetLevel();
}
- ++nFrom;
+ RowRef p = std::make_shared<XclExpRow>(GetRoot(), nFrom, maOutlineBfr, bRowAlwaysEmpty, bHidden, nHeight);
+ maRowMap.emplace(nFrom, p);
+ pPrevEntry = p;
}
+ ++nFrom;
}
itr = maRowMap.find(nXclRow);
return *itr->second;