diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2023-06-01 14:35:24 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2023-06-06 18:19:39 +0200 |
commit | e5fe8434110c1299527a0d03bf450e1b6d08ca57 (patch) | |
tree | bd12807e21465b2d2f5feb485abf3d1112b2836e /sc | |
parent | 4df278b4a98637aa5050abfd752eae0a9081b752 (diff) |
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.grandin@collabora.co.uk>
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/patattr.hxx | 2 | ||||
-rw-r--r-- | sc/source/core/data/patattr.cxx | 23 |
2 files changed, 21 insertions, 4 deletions
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: */ |