sw/source/core/txtnode/thints.cxx | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-)
New commits: commit d4ec4b875b952b05b8b1e0ba73dc31c1bcd27e43 Author: Noel Grandin <noel.gran...@collabora.co.uk> AuthorDate: Wed May 3 15:44:52 2023 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Wed May 3 19:13:03 2023 +0200 Portion can use sal_Int32 for its key which makes it a little more cache-dense on 64-bit platforms Change-Id: I6a7d22d94a04baac623a23d4766d4d8b7bbbb570 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/151325 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> diff --git a/sw/source/core/txtnode/thints.cxx b/sw/source/core/txtnode/thints.cxx index 5b5a8aa96f2e..75e80abb242a 100644 --- a/sw/source/core/txtnode/thints.cxx +++ b/sw/source/core/txtnode/thints.cxx @@ -2699,7 +2699,7 @@ void SwpHints::NoteInHistory( SwTextAttr *pAttr, const bool bNew ) namespace { struct Portion { SwTextAttr* pTextAttr; - int nKey; + sal_Int32 nKey; bool isRsidOnlyAutoFormat; }; typedef std::vector< Portion > PortionMap; commit e19c102e87002f953f2eb28c154da8f54b70068e Author: Noel Grandin <noel.gran...@collabora.co.uk> AuthorDate: Wed May 3 14:37:07 2023 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Wed May 3 19:12:52 2023 +0200 tdf#136991 speed up rtf load (*) since we are searching an ordered list, and we know that we want the "next" range, a linear search is faster than a binary search, especially when the list becomes large enough to exceed cache. (*) Since element "i" and element "i+1", we can start the second search where the first search left off (*) Since we are moving forward through the list, we can limit subsequent searches by the results from the previous loop search. This reduces the load time by 15% Change-Id: I460339e3bc12e0a8bea39334173a34b2aa79515d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/151323 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> diff --git a/sw/source/core/txtnode/thints.cxx b/sw/source/core/txtnode/thints.cxx index 229df8e3cda9..5b5a8aa96f2e 100644 --- a/sw/source/core/txtnode/thints.cxx +++ b/sw/source/core/txtnode/thints.cxx @@ -2782,15 +2782,16 @@ bool SwpHints::MergePortions( SwTextNode& rNode ) RsidOnlyAutoFormatFlagMap[nKey] = isRsidOnlyAutoFormat; } - // we add data strictly in-order, so we can binary-search the vector + // we add data strictly in-order, so we can forward-search the vector auto equal_range = [](PortionMap::const_iterator startIt, PortionMap::const_iterator endIt, int i) { - Portion key { nullptr, i, false }; - return std::equal_range(startIt, endIt, key, - [] (const Portion& lhs, const Portion& rhs) -> bool - { - return lhs.nKey < rhs.nKey; - }); + auto it1 = startIt; + while (it1 != endIt && it1->nKey < i) + ++it1; + auto it2 = it1; + while (it2 != endIt && it2->nKey == i) + ++it2; + return std::pair<PortionMap::const_iterator, PortionMap::const_iterator>{ it1, it2 }; }; // check if portion i can be merged with portion i+1: @@ -2798,13 +2799,14 @@ bool SwpHints::MergePortions( SwTextNode& rNode ) // IgnoreEnd at first / last portion int i = 0; int j = i + 1; - // Store these outside the loop, because we limit the search area on subsequent searches. + // Store this outside the loop, because we limit the search area on subsequent searches. std::pair< PortionMap::const_iterator, PortionMap::const_iterator > aRange1 { aPortionMap.begin(), aPortionMap.begin() + aPortionMap.size() }; while ( i <= nKey ) { aRange1 = equal_range( aRange1.first, aPortionMap.begin() + aPortionMap.size(), i ); + // start the search for this one from where the first search ended. std::pair< PortionMap::const_iterator, PortionMap::const_iterator > aRange2 - = equal_range( aRange1.first, aPortionMap.begin() + aPortionMap.size(), j ); + = equal_range( aRange1.second, aPortionMap.begin() + aPortionMap.size(), j ); MergeResult eMerge = lcl_Compare_Attributes(i, j, aRange1, aRange2, RsidOnlyAutoFormatFlagMap);