From 9fbf7a0b624aee6b116efdf69462e73f0275fab6 Mon Sep 17 00:00:00 2001 From: Jaime Torres Date: Sun, 4 Feb 2018 21:19:33 +0100 Subject: [PATCH] Faster drag&drop in directories with thousands of files Summary: The check is called when the mouse is moved in a drag&drop operation. Dragging all files in a directory with 3000 files under callgrind, moving the mouse to the other panel and then canceling, doing it twice, callgrind shows that the method urlListMatchesUrl is called around 200 times, spending around 9,30% of the cpu in those calls. Applying the patch, callgrind tells it uses now 0.31% of the cpu in 1208 calls. CCBUG: 342056 Reviewers: #dolphin, elvisangelaccio, markg Reviewed By: #dolphin, elvisangelaccio, markg Subscribers: markg, anthonyfieroni, michaelh, elvisangelaccio, ngraham Differential Revision: https://phabricator.kde.org/D10085 --- src/kitemviews/kitemlistcontroller.cpp | 3 +++ src/views/draganddrophelper.cpp | 20 +++++++++++++++++--- src/views/draganddrophelper.h | 10 ++++++++++ 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/kitemviews/kitemlistcontroller.cpp b/src/kitemviews/kitemlistcontroller.cpp index 130936488..7af8781b4 100644 --- a/src/kitemviews/kitemlistcontroller.cpp +++ b/src/kitemviews/kitemlistcontroller.cpp @@ -849,6 +849,9 @@ bool KItemListController::dragEnterEvent(QGraphicsSceneDragDropEvent* event, con { Q_UNUSED(event); Q_UNUSED(transform); + + DragAndDropHelper::clearUrlListMatchesUrlCache(); + return false; } diff --git a/src/views/draganddrophelper.cpp b/src/views/draganddrophelper.cpp index e944227df..4d76992ca 100644 --- a/src/views/draganddrophelper.cpp +++ b/src/views/draganddrophelper.cpp @@ -29,12 +29,21 @@ #include #include +QHash DragAndDropHelper::m_urlListMatchesUrlCache; bool DragAndDropHelper::urlListMatchesUrl(const QList& urls, const QUrl& destUrl) { - return std::find_if(urls.constBegin(), urls.constEnd(), [destUrl](const QUrl& url) { - return url.matches(destUrl, QUrl::StripTrailingSlash); - }) != urls.constEnd(); + auto iteratorResult = m_urlListMatchesUrlCache.constFind(destUrl); + if (iteratorResult != m_urlListMatchesUrlCache.constEnd()) { + return *iteratorResult; + } + + const bool destUrlMatches = + std::find_if(urls.constBegin(), urls.constEnd(), [destUrl](const QUrl& url) { + return url.matches(destUrl, QUrl::StripTrailingSlash); + }) != urls.constEnd(); + + return *m_urlListMatchesUrlCache.insert(destUrl, destUrlMatches); } KIO::DropJob* DragAndDropHelper::dropUrls(const QUrl& destUrl, QDropEvent* event, QWidget* window) @@ -63,3 +72,8 @@ KIO::DropJob* DragAndDropHelper::dropUrls(const QUrl& destUrl, QDropEvent* event return nullptr; } +void DragAndDropHelper::clearUrlListMatchesUrlCache() +{ + DragAndDropHelper::m_urlListMatchesUrlCache.clear(); +} + diff --git a/src/views/draganddrophelper.h b/src/views/draganddrophelper.h index e47f83ca8..0c7eadc6c 100644 --- a/src/views/draganddrophelper.h +++ b/src/views/draganddrophelper.h @@ -54,6 +54,16 @@ public: * @return True if destUrl is contained in the urls parameter. */ static bool urlListMatchesUrl(const QList& urls, const QUrl& destUrl); + + /** + * clear the internal cache. + */ + static void clearUrlListMatchesUrlCache(); +private: + /** + * Stores the results of the expensive checks made in urlListMatchesUrl. + */ + static QHash m_urlListMatchesUrlCache; }; #endif -- 2.47.3