summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2023-06-01 14:35:24 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2023-06-06 18:19:39 +0200
commite5fe8434110c1299527a0d03bf450e1b6d08ca57 (patch)
treebd12807e21465b2d2f5feb485abf3d1112b2836e /sc
parent4df278b4a98637aa5050abfd752eae0a9081b752 (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.hxx2
-rw-r--r--sc/source/core/data/patattr.cxx23
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: */