sc/inc/patattr.hxx | 2 +- sc/source/core/data/patattr.cxx | 23 ++++++++++++++++++++--- 2 files changed, 21 insertions(+), 4 deletions(-)
New commits: commit e5fe8434110c1299527a0d03bf450e1b6d08ca57 Author: Noel Grandin <noel.gran...@collabora.co.uk> AuthorDate: Thu Jun 1 14:35:24 2023 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Tue Jun 6 18:19:39 2023 +0200 use a SIMD friendly hashcode for ScPatternAttr which shaves 5% off load time of a large sheet with lots of formats. We are calculating a hash over a decent sized array of pointers, so unroll the loop and reduce data-dependencies to give the compiler (and the CPU) a chance to do work in parallel Change-Id: I3d58fcf547c9280437295b9c9ec10aff16419afc Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152443 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> diff --git a/sc/inc/patattr.hxx b/sc/inc/patattr.hxx index 5b031f488467..067193136fb9 100644 --- a/sc/inc/patattr.hxx +++ b/sc/inc/patattr.hxx @@ -53,7 +53,7 @@ enum ScAutoFontColorMode class SC_DLLPUBLIC ScPatternAttr final : public SfxSetItem { std::optional<OUString> pName; - mutable std::optional<size_t> mxHashCode; + mutable std::optional<sal_Int32> mxHashCode; ScStyleSheet* pStyle; sal_uInt64 mnKey; public: diff --git a/sc/source/core/data/patattr.cxx b/sc/source/core/data/patattr.cxx index 532831f90a78..d2be666aa349 100644 --- a/sc/source/core/data/patattr.cxx +++ b/sc/source/core/data/patattr.cxx @@ -52,6 +52,7 @@ #include <tools/fract.hxx> #include <tools/UnitConversion.hxx> #include <osl/diagnose.h> +#include <sal/log.hxx> #include <attrib.hxx> #include <patattr.hxx> @@ -64,7 +65,6 @@ #include <validat.hxx> #include <scmod.hxx> #include <fillinfo.hxx> -#include <boost/functional/hash.hpp> #include <comphelper/lok.hxx> #include <tabvwsh.hxx> @@ -1432,8 +1432,25 @@ void ScPatternAttr::CalcHashCode() const mxHashCode = 0; // invalid return; } - mxHashCode = 1; // Set up seed so that an empty pattern does not have an (invalid) hash of 0. - boost::hash_range(*mxHashCode, rSet.GetItems_Impl(), rSet.GetItems_Impl() + compareSize); + // This is an unrolled hash function so the compiler/CPU can execute it in parallel, + // because we hit this hard when loading documents with lots of styles. + // Set up seed so that an empty pattern does not have an (invalid) hash of 0. + sal_Int32 h1 = 1; + sal_Int32 h2 = 1; + sal_Int32 h3 = 1; + sal_Int32 h4 = 1; + for (auto it = rSet.GetItems_Impl(), end = rSet.GetItems_Impl() + (compareSize / 4 * 4); it != end; ) + { + h1 = 31 * h1 + reinterpret_cast<size_t>(*it); + ++it; + h2 = 31 * h2 + reinterpret_cast<size_t>(*it); + ++it; + h3 = 31 * h3 + reinterpret_cast<size_t>(*it); + ++it; + h4 = 31 * h4 + reinterpret_cast<size_t>(*it); + ++it; + } + mxHashCode = h1 + h2 + h3 + h4; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */