From cbaf52b09971edf6f3e1458f7dd677b80a1568ed Mon Sep 17 00:00:00 2001
From: Konstantin Ritt <ritt.ks@gmail.com>
Date: Mon, 16 Apr 2012 14:43:27 +0300
Subject: [PATCH] QThreadPool: optimize enqueueTask() for common case

the most-common case is: queue is empty or filled with tasks of
the same priority; so the runnable would be put at the end of queue.
both checks are cheap for us.

also avoid detach()'ing by using const iterators

Change-Id: Iab2255f852211f9accc8d717f778671661210ef3
Reviewed-by: Bradley T. Hughes <bradley.hughes@nokia.com>
---
 src/corelib/thread/qthreadpool.cpp | 22 ++++++++++------------
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/src/corelib/thread/qthreadpool.cpp b/src/corelib/thread/qthreadpool.cpp
index b7021817c52..870f943a63c 100644
--- a/src/corelib/thread/qthreadpool.cpp
+++ b/src/corelib/thread/qthreadpool.cpp
@@ -47,15 +47,6 @@
 
 QT_BEGIN_NAMESPACE
 
-inline bool operator<(int priority, const QPair<QRunnable *, int> &p)
-{
-    return p.second < priority;
-}
-inline bool operator<(const QPair<QRunnable *, int> &p, int priority)
-{
-    return priority < p.second;
-}
-
 Q_GLOBAL_STATIC(QThreadPool, theInstance)
 
 /*
@@ -209,15 +200,22 @@ bool QThreadPoolPrivate::tryStart(QRunnable *task)
     return true;
 }
 
+inline bool operator<(int priority, const QPair<QRunnable *, int> &p)
+{ return p.second < priority; }
+inline bool operator<(const QPair<QRunnable *, int> &p, int priority)
+{ return priority < p.second; }
+
 void QThreadPoolPrivate::enqueueTask(QRunnable *runnable, int priority)
 {
     if (runnable->autoDelete())
         ++runnable->ref;
 
     // put it on the queue
-    QList<QPair<QRunnable *, int> >::iterator at =
-        qUpperBound(queue.begin(), queue.end(), priority);
-    queue.insert(at, qMakePair(runnable, priority));
+    QList<QPair<QRunnable *, int> >::const_iterator begin = queue.constBegin();
+    QList<QPair<QRunnable *, int> >::const_iterator it = queue.constEnd();
+    if (it != begin && priority < (*(it - 1)).second)
+        it = qUpperBound(begin, --it, priority);
+    queue.insert(it - begin, qMakePair(runnable, priority));
     runnableReady.wakeOne();
 }
 
-- 
GitLab