sc/source/core/tool/interpr1.cxx | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-)
New commits: commit c05c826bd18eedaa7720ff0817b5c796435dbc02 Author: Luboš Luňák <l.lu...@collabora.com> AuthorDate: Tue May 10 21:47:44 2022 +0200 Commit: Luboš Luňák <l.lu...@collabora.com> CommitDate: Wed May 11 11:52:31 2022 +0200 search faster an array where most elements do not match (tdf#144777) As said in previous commits, clearing and searching this array can be the major cost of large *IFS operations. And memchr() can do way better than what the compiler generates. Change-Id: Ibcaad05356f9fa33997593f929522b325c026579 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134139 Tested-by: Jenkins Reviewed-by: Luboš Luňák <l.lu...@collabora.com> diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx index ce05f771bd6d..81b75fe21cd5 100644 --- a/sc/source/core/tool/interpr1.cxx +++ b/sc/source/core/tool/interpr1.cxx @@ -6465,10 +6465,20 @@ void ScInterpreter::IterateParametersIfs( double(*ResultFunc)( const sc::ParamIf // COUNTIFS only. if (vRefArrayConditions.empty()) { - for (auto const & rCond : vConditions) - { - if (rCond == nQueryCount) - ++aRes.mfCount; + // The code below is this but optimized for most elements not matching. + // for (auto const & rCond : vConditions) + // if (rCond == nQueryCount) + // ++aRes.mfCount; + static_assert(sizeof(vConditions[0]) == 1); + const sal_uInt8* pos = vConditions.data(); + const sal_uInt8* end = pos + vConditions.size(); + for(;;) + { + pos = static_cast< const sal_uInt8* >( memchr( pos, nQueryCount, end - pos )); + if( pos == nullptr ) + break; + ++aRes.mfCount; + ++pos; } } else