diff options
author | Luboš Luňák <l.lunak@collabora.com> | 2021-11-08 17:29:41 +0100 |
---|---|---|
committer | Luboš Luňák <l.lunak@collabora.com> | 2021-11-08 20:34:23 +0100 |
commit | ec0edb0969c23b25576f4d1b3b2ee5d3f21990ad (patch) | |
tree | b3ac7b7d55455e4dc0df4cf2348988f74ca1719a /sc | |
parent | 1a588c71a0b60d200077138eaff54fced14c4fe2 (diff) |
optimize VLOOKUP by returning SharedString if possible (tdf#139444)
Profiling shows that the slowness mostly comes from converting
the cell's SharedString to OUString and then the comparison
converts it back. To improve performance, return the SharedString
if possible and ignore the OUString.
Change-Id: Idb190bd0354cea3185e5ff9ebaf92cab63f23f70
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/124880
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/cellform.hxx | 11 | ||||
-rw-r--r-- | sc/inc/column.hxx | 12 | ||||
-rw-r--r-- | sc/inc/document.hxx | 4 | ||||
-rw-r--r-- | sc/inc/table.hxx | 3 | ||||
-rw-r--r-- | sc/source/core/data/column3.cxx | 4 | ||||
-rw-r--r-- | sc/source/core/data/document.cxx | 4 | ||||
-rw-r--r-- | sc/source/core/data/table2.cxx | 4 | ||||
-rw-r--r-- | sc/source/core/data/table3.cxx | 11 | ||||
-rw-r--r-- | sc/source/core/tool/cellform.cxx | 17 |
9 files changed, 52 insertions, 18 deletions
diff --git a/sc/inc/cellform.hxx b/sc/inc/cellform.hxx index 65d0fc232ee9..cd9b28f7692c 100644 --- a/sc/inc/cellform.hxx +++ b/sc/inc/cellform.hxx @@ -21,6 +21,7 @@ #include "scdllapi.h" #include <rtl/ustring.hxx> +#include <svl/sharedstring.hxx> class SvNumberFormatter; class Color; @@ -42,9 +43,17 @@ public: const Color** ppColor, SvNumberFormatter& rFormatter, bool bNullVals = true, bool bFormula = false ); + // Note that if pShared is set and a value is returned that way, the returned OUString is empty. static OUString GetInputString( const ScRefCellValue& rCell, sal_uInt32 nFormat, SvNumberFormatter& rFormatter, - const ScDocument& rDoc, bool bFiltering = false ); + const ScDocument& rDoc, const svl::SharedString** pShared = nullptr, bool bFiltering = false ); + + static OUString GetInputString( + const ScRefCellValue& rCell, sal_uInt32 nFormat, SvNumberFormatter& rFormatter, + const ScDocument& rDoc, bool bFiltering) + { + return GetInputString( rCell, nFormat, rFormatter, rDoc, nullptr, bFiltering ); + } static OUString GetOutputString( ScDocument& rDoc, const ScAddress& rPos, const ScRefCellValue& rCell ); diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index c25de8a028bc..91e5b5c3fc22 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -368,10 +368,12 @@ public: const ScInterpreterContext* pContext = nullptr ) const { return GetString( GetCellValue( rBlockPos, nRow ), nRow, pContext ); } double* GetValueCell( SCROW nRow ); - OUString GetInputString( SCROW nRow ) const - { return GetInputString( GetCellValue( nRow ), nRow ); } - OUString GetInputString( sc::ColumnBlockConstPosition& rBlockPos, SCROW nRow ) const - { return GetInputString( GetCellValue( rBlockPos, nRow ), nRow ); } + // Note that if pShared is set and a value is returned that way, the returned OUString is empty. + OUString GetInputString( SCROW nRow, const svl::SharedString** pShared = nullptr ) const + { return GetInputString( GetCellValue( nRow ), nRow, pShared ); } + OUString GetInputString( sc::ColumnBlockConstPosition& rBlockPos, SCROW nRow, + const svl::SharedString** pShared = nullptr ) const + { return GetInputString( GetCellValue( rBlockPos, nRow ), nRow, pShared ); } double GetValue( SCROW nRow ) const; const EditTextObject* GetEditText( SCROW nRow ) const; void RemoveEditTextCharAttribs( SCROW nRow, const ScPatternAttr& rAttr ); @@ -747,7 +749,7 @@ private: SCROW FindNextVisibleRow(SCROW nRow, bool bForward) const; OUString GetString( const ScRefCellValue& cell, SCROW nRow, const ScInterpreterContext* pContext = nullptr ) const; - OUString GetInputString( const ScRefCellValue& cell, SCROW nRow ) const; + OUString GetInputString( const ScRefCellValue& cell, SCROW nRow, const svl::SharedString** pShared = nullptr ) const; /** * Called whenever the state of cell array gets modified i.e. new cell diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index 7ff8fbcb4fbe..0ed322c541ab 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -1189,7 +1189,9 @@ public: void BlockFormulaGroupContextDiscard( bool block ) { mbFormulaGroupCxtBlockDiscard = block; } - SC_DLLPUBLIC OUString GetInputString( SCCOL nCol, SCROW nRow, SCTAB nTab ) const; + // Note that if pShared is set and a value is returned that way, the returned OUString is empty. + SC_DLLPUBLIC OUString GetInputString( SCCOL nCol, SCROW nRow, SCTAB nTab, + const svl::SharedString** pShared = nullptr ) const; FormulaError GetStringForFormula( const ScAddress& rPos, OUString& rString ); SC_DLLPUBLIC double GetValue( const ScAddress& rPos ) const; SC_DLLPUBLIC double GetValue( SCCOL nCol, SCROW nRow, SCTAB nTab ) const; diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx index 06dca697c790..40806e70f31a 100644 --- a/sc/inc/table.hxx +++ b/sc/inc/table.hxx @@ -448,7 +448,8 @@ public: void SetRawString( SCCOL nCol, SCROW nRow, const svl::SharedString& rStr ); OUString GetString( SCCOL nCol, SCROW nRow, const ScInterpreterContext* pContext = nullptr ) const; double* GetValueCell( SCCOL nCol, SCROW nRow ); - OUString GetInputString( SCCOL nCol, SCROW nRow ) const; + // Note that if pShared is set and a value is returned that way, the returned OUString is empty. + OUString GetInputString( SCCOL nCol, SCROW nRow, const svl::SharedString** pShared = nullptr ) const; double GetValue( SCCOL nCol, SCROW nRow ) const; const EditTextObject* GetEditText( SCCOL nCol, SCROW nRow ) const; void RemoveEditTextCharAttribs( SCCOL nCol, SCROW nRow, const ScPatternAttr& rAttr ); diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx index dfc6b23a5fba..8361018c41c8 100644 --- a/sc/source/core/data/column3.cxx +++ b/sc/source/core/data/column3.cxx @@ -2996,10 +2996,10 @@ double* ScColumn::GetValueCell( SCROW nRow ) return &sc::numeric_block::at(*it->data, aPos.second); } -OUString ScColumn::GetInputString( const ScRefCellValue& aCell, SCROW nRow ) const +OUString ScColumn::GetInputString( const ScRefCellValue& aCell, SCROW nRow, const svl::SharedString** pShared ) const { sal_uLong nFormat = GetNumberFormat(GetDoc().GetNonThreadedContext(), nRow); - return ScCellFormat::GetInputString(aCell, nFormat, *(GetDoc().GetFormatTable()), GetDoc()); + return ScCellFormat::GetInputString(aCell, nFormat, *(GetDoc().GetFormatTable()), GetDoc(), pShared); } double ScColumn::GetValue( SCROW nRow ) const diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index 71665e4d6ad6..a16c82bf33ff 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -3561,10 +3561,10 @@ void ScDocument::DiscardFormulaGroupContext() mpFormulaGroupCxt.reset(); } -OUString ScDocument::GetInputString( SCCOL nCol, SCROW nRow, SCTAB nTab ) const +OUString ScDocument::GetInputString( SCCOL nCol, SCROW nRow, SCTAB nTab, const svl::SharedString** pShared ) const { if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] ) - return maTabs[nTab]->GetInputString( nCol, nRow ); + return maTabs[nTab]->GetInputString( nCol, nRow, pShared ); else return OUString(); } diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index 70fb4e798555..b234825546a1 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -1756,10 +1756,10 @@ double* ScTable::GetValueCell( SCCOL nCol, SCROW nRow ) return CreateColumnIfNotExists(nCol).GetValueCell(nRow); } -OUString ScTable::GetInputString( SCCOL nCol, SCROW nRow ) const +OUString ScTable::GetInputString( SCCOL nCol, SCROW nRow, const svl::SharedString** pShared ) const { if (ValidColRow(nCol, nRow) && nCol < GetAllocatedColumnsCount()) - return aCol[nCol].GetInputString( nRow ); + return aCol[nCol].GetInputString( nRow, pShared ); else return OUString(); } diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx index db4e9c25ec24..9c7417278658 100644 --- a/sc/source/core/data/table3.cxx +++ b/sc/source/core/data/table3.cxx @@ -2607,13 +2607,20 @@ public: sal_uInt32 nFormat = pContext ? mrTab.GetNumberFormat( *pContext, ScAddress(static_cast<SCCOL>(rEntry.nField), nRow, mrTab.GetTab()) ) : mrTab.GetNumberFormat( static_cast<SCCOL>(rEntry.nField), nRow ); SvNumberFormatter* pFormatter = pContext ? pContext->GetFormatTable() : mrDoc.GetFormatTable(); - OUString aStr = ScCellFormat::GetInputString(rCell, nFormat, *pFormatter, mrDoc, rEntry.bDoQuery); + const svl::SharedString* sharedString = nullptr; + OUString aStr = ScCellFormat::GetInputString(rCell, nFormat, *pFormatter, mrDoc, &sharedString, rEntry.bDoQuery); + // Use the shared string for less conversions, if available. + if( sharedString != nullptr ) + return compareByStringComparator(rEntry, rItem, sharedString, nullptr); return compareByStringComparator(rEntry, rItem, nullptr, &aStr); } } else { - OUString aStr = mrTab.GetInputString(static_cast<SCCOL>(rEntry.nField), nRow); + const svl::SharedString* sharedString = nullptr; + OUString aStr = mrTab.GetInputString(static_cast<SCCOL>(rEntry.nField), nRow, &sharedString); + if( sharedString != nullptr ) + return compareByStringComparator(rEntry, rItem, sharedString, nullptr); return compareByStringComparator(rEntry, rItem, nullptr, &aStr); } } diff --git a/sc/source/core/tool/cellform.cxx b/sc/source/core/tool/cellform.cxx index dd52379bbc29..699f7d88cecb 100644 --- a/sc/source/core/tool/cellform.cxx +++ b/sc/source/core/tool/cellform.cxx @@ -128,7 +128,8 @@ OUString ScCellFormat::GetString( } OUString ScCellFormat::GetInputString( - const ScRefCellValue& rCell, sal_uInt32 nFormat, SvNumberFormatter& rFormatter, const ScDocument& rDoc, bool bFiltering ) + const ScRefCellValue& rCell, sal_uInt32 nFormat, SvNumberFormatter& rFormatter, const ScDocument& rDoc, + const svl::SharedString** pShared, bool bFiltering ) { switch (rCell.meType) { @@ -151,11 +152,23 @@ OUString ScCellFormat::GetInputString( else if (pFC->IsValue()) rFormatter.GetInputLineString(pFC->GetValue(), nFormat, str, bFiltering); else - str = pFC->GetString().getString(); + { + const svl::SharedString& shared = pFC->GetString(); + // Allow callers to optimize by avoiding converting later back to OUString. + // To avoid refcounting that won't be needed, do not even return the OUString. + if( pShared != nullptr ) + *pShared = &shared; + else + str = shared.getString(); + } const FormulaError nErrCode = pFC->GetErrCode(); if (nErrCode != FormulaError::NONE) + { str.clear(); + if( pShared != nullptr ) + *pShared = nullptr; + } return str; } |