Optimize QInotifyFileSystemWatcherEngine::getPathFromID()
The code basically wants to get the last element of equal_range(id). The problem is that backwards iteration on QHash is very expensive, because it's implemented as forward search with wrap-around at bucket end. So it was implementing its own equal_range with look-ahead. The problem is that it compared each key in the equal_range twice: once in the if, and once more in the following while iteration. I expect to see this kind of algorithm more as we move away from the fake bidirectionalism of QHash, so I decided to implement it in a generic way. We can copy it somewhere else when we find more users. Change-Id: I7951652107ab897f6a456035f02e0339835e078d Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This commit is contained in:
parent
a7383b4b6d
commit
2e5b8032a2
@ -422,16 +422,27 @@ void QInotifyFileSystemWatcherEngine::readFromInotify()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Hash, typename Key>
|
||||||
|
typename Hash::const_iterator
|
||||||
|
find_last_in_equal_range(const Hash &c, const Key &key)
|
||||||
|
{
|
||||||
|
// find c.equal_range(key).second - 1 without backwards iteration:
|
||||||
|
auto i = c.find(key);
|
||||||
|
const auto end = c.cend();
|
||||||
|
if (i == end)
|
||||||
|
return end;
|
||||||
|
decltype(i) prev;
|
||||||
|
do {
|
||||||
|
prev = i;
|
||||||
|
++i;
|
||||||
|
} while (i != end && i.key() == key);
|
||||||
|
return prev;
|
||||||
|
}
|
||||||
|
|
||||||
QString QInotifyFileSystemWatcherEngine::getPathFromID(int id) const
|
QString QInotifyFileSystemWatcherEngine::getPathFromID(int id) const
|
||||||
{
|
{
|
||||||
QHash<int, QString>::const_iterator i = idToPath.find(id);
|
auto i = find_last_in_equal_range(idToPath, id);
|
||||||
while (i != idToPath.constEnd() && i.key() == id) {
|
return i == idToPath.cend() ? QString() : i.value() ;
|
||||||
if ((i + 1) == idToPath.constEnd() || (i + 1).key() != id) {
|
|
||||||
return i.value();
|
|
||||||
}
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
return QString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
Loading…
x
Reference in New Issue
Block a user