Fix KFileItemModel performance regression

Commit 119f7a3f fixed a crash that was caused by the porting of the
natural sorting code to QCollator. QCollator is not thread-safe, so
every thread needs its own instance. However, that commit made every
recursive call in the sorting code create a new deep-copied QCollator
instance, which is quite expensive and thus made inserting any items
into the model very slow (this could also be seen in the KFileItemModel
benchmark).

This commit avoids unnecessary QCollator copying by forcing all sorting
functions which are called in the same thread to pass the 'lessThan'
object by const reference, such that no unnecessary copying of that
object, including a deep copy of the QCollator, takes place.

REVIEW: 123620
This commit is contained in:
Frank Reininghaus 2015-05-07 21:09:01 +01:00
parent 5bde333ca7
commit e69d348975

View file

@ -37,7 +37,7 @@
template <typename RandomAccessIterator, typename LessThan>
static void mergeSort(RandomAccessIterator begin,
RandomAccessIterator end,
LessThan lessThan)
const LessThan& lessThan)
{
// The implementation is based on qStableSortHelper() from qalgorithms.h
// Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
@ -99,7 +99,7 @@ template <typename RandomAccessIterator, typename LessThan>
static void merge(RandomAccessIterator begin,
RandomAccessIterator pivot,
RandomAccessIterator end,
LessThan lessThan)
const LessThan& lessThan)
{
// The implementation is based on qMerge() from qalgorithms.h
// Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
@ -124,12 +124,14 @@ static void merge(RandomAccessIterator begin,
if (len1 > len2) {
const int len1Half = len1 / 2;
firstCut = begin + len1Half;
secondCut = std::lower_bound(pivot, end, *firstCut, lessThan);
secondCut = std::lower_bound<RandomAccessIterator,
decltype(*firstCut), const LessThan&>(pivot, end, *firstCut, lessThan);
len2Half = secondCut - pivot;
} else {
len2Half = len2 / 2;
secondCut = pivot + len2Half;
firstCut = std::upper_bound(begin, pivot, *secondCut, lessThan);
firstCut = std::upper_bound<RandomAccessIterator,
decltype(*secondCut), const LessThan&>(begin, pivot, *secondCut, lessThan);
}
std::rotate(firstCut, pivot, secondCut);