diff options
author | Noel Grandin <noel@peralex.com> | 2021-04-13 14:03:53 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2021-04-13 16:00:28 +0200 |
commit | 64152322b99556b2e80a58cdf04a586e6941ba10 (patch) | |
tree | cc4f33b084d46ba327f0c0ca5862cb3e5518763a /sc | |
parent | f01ba45e59696aa1a5e500a96c8ec7c40491da35 (diff) |
tdf#130326 speed up row height calculated
for scaled rows. Teach the ForwardIterator to use the slightly
faster normal search, and make getRangeData cache the resulting
iterator even when doing a tree search. The combination of
tree search for the first item, and then using a cached iterator
to step through the row data is fairly fast.
Take my load time from 23s to 22.3s
Change-Id: Icd1aa3d3a8022a073b125dfc05a670b75da1837e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114045
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'sc')
-rw-r--r-- | sc/source/core/data/segmenttree.cxx | 25 | ||||
-rw-r--r-- | sc/source/core/data/table2.cxx | 9 |
2 files changed, 23 insertions, 11 deletions
diff --git a/sc/source/core/data/segmenttree.cxx b/sc/source/core/data/segmenttree.cxx index 3233a074ac06..77d1e329a839 100644 --- a/sc/source/core/data/segmenttree.cxx +++ b/sc/source/core/data/segmenttree.cxx @@ -247,10 +247,10 @@ bool ScFlatSegmentsImpl<ValueType_, ExtValueType_>::getRangeData(SCCOLROW nPos, maSegments.build_tree(); } - auto it = maSegments.search_tree(nPos, rData.mnValue, &rData.mnPos1, &rData.mnPos2); - if (!it.second) + auto [it,found] = maSegments.search_tree(nPos, rData.mnValue, &rData.mnPos1, &rData.mnPos2); + if (!found) return false; - + maItr = it; // cache the iterator to speed up ForwardIterator. rData.mnPos2 = rData.mnPos2-1; // end point is not inclusive. return true; } @@ -597,12 +597,23 @@ bool ScFlatUInt16RowSegments::ForwardIterator::getValue(SCROW nPos, sal_uInt16& if (mnCurPos > mnLastPos) { // position not in the current segment. Update the current value. - ScFlatUInt16RowSegments::RangeData aData; - if (!mrSegs.getRangeData(mnCurPos, aData)) - return false; + ScFlatUInt16SegmentsImpl::RangeData aData; + if (mnLastPos == -1) + { + // first time in this method, use the tree search based method + if (!mrSegs.mpImpl->getRangeData(mnCurPos, aData)) + return false; + } + else + { + // but on subsequent calls, use the leaf method, which is faster + // because we have a cached iterator. + if (!mrSegs.mpImpl->getRangeDataLeaf(mnCurPos, aData)) + return false; + } mnCurValue = aData.mnValue; - mnLastPos = aData.mnRow2; + mnLastPos = aData.mnPos2; } rVal = mnCurValue; diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index a94d07bf5032..a86c95da082d 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -3307,16 +3307,17 @@ sal_uLong ScTable::GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow, double fS nLastRow = nEndRow; // #i117315# can't use getSumValue, because individual values must be rounded + ScFlatUInt16RowSegments::ForwardIterator aSegmentIter(*mpRowHeights); while (nRow <= nLastRow) { - ScFlatUInt16RowSegments::RangeData aData; - if (!mpRowHeights->getRangeData(nRow, aData)) + sal_uInt16 nRowVal; + if (!aSegmentIter.getValue(nRow, nRowVal)) return nHeight; // shouldn't happen - SCROW nSegmentEnd = std::min( nLastRow, aData.mnRow2 ); + SCROW nSegmentEnd = std::min( nLastRow, aSegmentIter.getLastPos() ); // round-down a single height value, multiply resulting (pixel) values - const sal_uLong nOneHeight = static_cast<sal_uLong>( aData.mnValue * fScale ); + const sal_uLong nOneHeight = static_cast<sal_uLong>( nRowVal * fScale ); // sometimes scaling results in zero height if (nOneHeight) { |