diff options
author | Luboš Luňák <l.lunak@collabora.com> | 2022-02-20 10:11:15 +0100 |
---|---|---|
committer | Luboš Luňák <l.lunak@collabora.com> | 2022-02-20 11:44:15 +0100 |
commit | 9c7f3ddf5b3c23de0fed08fa3ebdfa2a95fec588 (patch) | |
tree | 65d3b53be6f3577f36304e40fd0eacf4e55bd29b /sc | |
parent | fdcea8ccc8236b0975ac9c85dcabf9c663e4b627 (diff) |
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>
Diffstat (limited to 'sc')
-rw-r--r-- | sc/source/filter/excel/xetable.cxx | 96 |
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; |