sc/source/filter/excel/xetable.cxx |   29 +++++++++++++++++++++--------
 1 file changed, 21 insertions(+), 8 deletions(-)

New commits:
commit 09e9274fc080b471393b806617eb03124db67590
Author: Justin Luth <justin_l...@sil.org>
Date:   Wed Feb 8 19:08:07 2017 +0300

    Optimize Excel GetOrCreateRow: reduce loops
    
    for ( size_t nFrom = maRowMap.size(); nFrom <= nXclRow; ++nFrom )
    
    This previous code worked best under the assumption
    that every row is added to the map. However, the size of the
    map actually has no correlation to the row numbers contained in it
    when many rows are identical to each other (think silly formatting
    and empty rows - related to tdf#105840)
    Thus row 1,000,000 could occupy slot 2, and every access of that row
    would then trigger nearly 1 million redundant loops.
    
    Optimize:
    -check to see if the row already exists - if so do nothing.
    -existance of higher rows indicates there are no missing rows.
    -build missing rows from the previously-mapped row.
    
    Change-Id: Ib02520a1bf0f77b5ca0ec5ad3165ff7ea879515f
    Reviewed-on: https://gerrit.libreoffice.org/34038
    Tested-by: Jenkins <c...@libreoffice.org>
    Reviewed-by: Bartosz Kosiorek <gan...@poczta.onet.pl>

diff --git a/sc/source/filter/excel/xetable.cxx 
b/sc/source/filter/excel/xetable.cxx
index a8627c0..0c573e9 100644
--- a/sc/source/filter/excel/xetable.cxx
+++ b/sc/source/filter/excel/xetable.cxx
@@ -2375,18 +2375,31 @@ void XclExpRowBuffer::SaveXml( XclExpXmlStream& rStrm )
 
 XclExpRow& XclExpRowBuffer::GetOrCreateRow( sal_uInt32 nXclRow, bool 
bRowAlwaysEmpty )
 {
-    RowMap::iterator itr = maRowMap.begin();
-    ScDocument& rDoc = GetRoot().GetDoc();
-    SCTAB nScTab = GetRoot().GetCurrScTab();
-    for ( size_t nFrom = maRowMap.size(); nFrom <= nXclRow; ++nFrom )
+    RowMap::iterator 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 )
     {
-        itr = maRowMap.find(nFrom);
-        if ( itr == maRowMap.end() )
+        size_t nFrom = 0;
+        if( itr != maRowMap.begin() )
+        {
+            --itr;
+            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, for rows that height differ from 
previous,
             // if row is collapsed, has outline level (tdf#100347), or row is 
hidden (tdf#98106).
-            bool bHidden = rDoc.RowHidden(nFrom, nScTab);
+            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.
@@ -2403,11 +2416,11 @@ XclExpRow& XclExpRowBuffer::GetOrCreateRow( sal_uInt32 
nXclRow, bool bRowAlwaysE
                 RowRef p(new XclExpRow(GetRoot(), nFrom, maOutlineBfr, 
bRowAlwaysEmpty, bHidden, nHeight));
                 maRowMap.insert(RowMap::value_type(nFrom, p));
             }
+            ++nFrom;
         }
     }
     itr = maRowMap.find(nXclRow);
     return *itr->second;
-
 }
 
 // Cell Table
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to