diff options
author | Kohei Yoshida <kohei.yoshida@collabora.com> | 2013-10-20 13:41:58 -0400 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@collabora.com> | 2013-10-20 13:44:43 -0400 |
commit | 2d41f3acc359643a88bd39ef8c8d7bac106765fa (patch) | |
tree | 45940e40e336b26dc650e39bb7c81fc84c2daf23 | |
parent | 426708e70807e052aca2ec16314c103b1d2a0439 (diff) |
Reduce branching on empty matrix elements as well.
This makes a big difference in performance.
Change-Id: I88b48d10ff575d80c1c139278dc207d921f15848
-rw-r--r-- | sc/inc/compare.hxx | 5 | ||||
-rw-r--r-- | sc/source/core/tool/compare.cxx | 20 | ||||
-rw-r--r-- | sc/source/core/tool/scmatrix.cxx | 20 |
3 files changed, 37 insertions, 8 deletions
diff --git a/sc/inc/compare.hxx b/sc/inc/compare.hxx index 5f9e1585ca28..485f882878b5 100644 --- a/sc/inc/compare.hxx +++ b/sc/inc/compare.hxx @@ -70,6 +70,11 @@ double CompareFunc( double fCell1, const Compare::Cell& rCell2, CompareOptions* double CompareFunc( const Compare::Cell& rCell1, double fCell2, CompareOptions* pOptions = NULL ); double CompareFunc( double fCell1, double fCell2 ); +/** + * Left cell is empty while the right cell is numeric. + */ +double CompareEmptyToNumericFunc( double fCell2 ); + } #endif diff --git a/sc/source/core/tool/compare.cxx b/sc/source/core/tool/compare.cxx index a876fb1686c4..36e18bc5279b 100644 --- a/sc/source/core/tool/compare.cxx +++ b/sc/source/core/tool/compare.cxx @@ -357,6 +357,26 @@ double CompareFunc( double fCell1, double fCell2 ) return fRes; } +double CompareEmptyToNumericFunc( double fCell2 ) +{ + // Keep DoubleError if encountered + // #i40539# if bEmpty is set, bVal/nVal are uninitialized + if (!rtl::math::isFinite(fCell2)) + return fCell2; + + double fRes = 0; + if (fCell2 != 0.0) + { + if (fCell2 < 0.0) + fRes = 1; // empty cell > -x + else + fRes = -1; // empty cell < x + } + // else: empty cell == 0.0 + + return fRes; +} + } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx index a195a4ff8087..1a5ebbbdafc4 100644 --- a/sc/source/core/tool/scmatrix.cxx +++ b/sc/source/core/tool/scmatrix.cxx @@ -1359,6 +1359,13 @@ class CompareMatrixToNumericFunc : std::unary_function<MatrixImplType::element_b maResValues.push_back(evaluate(fVal, mrComp.meOp)); } + void compareLeftEmpty( size_t nSize ) + { + double fVal = sc::CompareEmptyToNumericFunc(mfRightValue); + bool bRes = evaluate(fVal, mrComp.meOp); + maResValues.resize(maResValues.size() + nSize, bRes); + } + public: CompareMatrixToNumericFunc( size_t nResSize, sc::Compare& rComp, double fRightValue, sc::CompareOptions* pOptions ) : mrComp(rComp), mfRightValue(fRightValue), mpOptions(pOptions) @@ -1409,13 +1416,8 @@ public: } break; case mdds::mtm::element_empty: - { - rCell.mbValue = false; - rCell.mbEmpty = true; - rCell.maStr = svl::SharedString::getEmptyString(); - for (size_t i = 0; i < node.size; ++i) - compare(); - } + compareLeftEmpty(node.size); + break; default: ; } @@ -1627,7 +1629,9 @@ ScMatrixRef ScMatrixImpl::CompareMatrix( { if (rComp.maCells[1].mbValue && !rComp.maCells[1].mbEmpty) { - // Matrix on the left, and a numeric value on the right. + // Matrix on the left, and a numeric value on the right. Use a + // function object that has much less branching for much better + // performance. CompareMatrixToNumericFunc aFunc(nSize, rComp, rComp.maCells[1].mfValue, pOptions); maMat.walk(aFunc); |