summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2017-09-05 19:48:30 +0200
committerLars Knoll <lars.knoll@qt.io>2017-09-06 18:10:44 +0000
commitec95ed168ace9358596d995c984ba969cb9975ca (patch)
tree6ef69786b6979e8884981ad62abdeb2c5caa8583
parent6000d6f561f284b57312c7a5274ec724aaac44e9 (diff)
Fix StringToInt implementation
Reduces the overhead per call of lookupId() from around 7000 to 180 instructions for a use case. Should in general scale much better. I still do not like that this is using global static data that is never cleaned up. It should be tied at the minimum to the lifetime of the Qt 3D scene. Change-Id: I777a2bbf2d765f4b0fc9e3d2b06692c7260f5a9f Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
-rw-r--r--src/render/backend/stringtoint.cpp61
-rw-r--r--src/render/backend/stringtoint_p.h5
2 files changed, 19 insertions, 47 deletions
diff --git a/src/render/backend/stringtoint.cpp b/src/render/backend/stringtoint.cpp
index 4ae49fc30..5659da394 100644
--- a/src/render/backend/stringtoint.cpp
+++ b/src/render/backend/stringtoint.cpp
@@ -40,6 +40,7 @@
#include "stringtoint_p.h"
#include <QMutex>
#include <QReadWriteLock>
+#include <QHash>
QT_BEGIN_NAMESPACE
@@ -49,15 +50,12 @@ namespace Render {
namespace {
-QMutex mutex;
-QReadWriteLock readLock;
+QReadWriteLock lock;
+QHash<QString, int> map = QHash<QString, int>();
+QVector<QString> reverseMap = QVector<QString>();
} // anonymous
-QVector<QString> StringToInt::m_stringsArray = QVector<QString>();
-QVector<QString> StringToInt::m_pendingStringsArray = QVector<QString>();
-int StringToInt::m_calls = 0;
-
int StringToInt::lookupId(QLatin1String str)
{
// ### optimize me
@@ -66,36 +64,20 @@ int StringToInt::lookupId(QLatin1String str)
int StringToInt::lookupId(const QString &str)
{
- // Note: how do we protect against the case where
- // we are synching the two arrays ?
- QReadLocker readLocker(&readLock);
- int idx = StringToInt::m_stringsArray.indexOf(str);
+ int idx;
+ {
+ QReadLocker readLocker(&lock);
+ idx = map.value(str, -1);
+ }
if (Q_UNLIKELY(idx < 0)) {
- QMutexLocker lock(&mutex);
-
- // If not found in m_stringsArray, maybe it's in the pending array
- if ((idx = StringToInt::m_pendingStringsArray.indexOf(str)) >= 0) {
- idx += StringToInt::m_stringsArray.size();
- } else {
- // If not, we add it to the m_pendingStringArray
- StringToInt::m_pendingStringsArray.push_back(str);
- idx = StringToInt::m_stringsArray.size() + m_pendingStringsArray.size() - 1;
- }
-
- // We sync the two arrays every 20 calls
- if (StringToInt::m_calls % 20 == 0 && StringToInt::m_pendingStringsArray.size() > 0) {
- // Unlock reader to writeLock
- // since a read lock cannot be locked for writing
- lock.unlock();
- readLocker.unlock();
-
- QWriteLocker writeLock(&readLock);
- lock.relock();
-
- StringToInt::m_stringsArray += StringToInt::m_pendingStringsArray;
- StringToInt::m_pendingStringsArray.clear();
- StringToInt::m_calls = 0;
+ QWriteLocker writeLocker(&lock);
+ idx = map.value(str, -1);
+ if (idx < 0) {
+ idx = reverseMap.size();
+ Q_ASSERT(map.size() == reverseMap.size());
+ map.insert(str, idx);
+ reverseMap.append(str);
}
}
return idx;
@@ -103,14 +85,9 @@ int StringToInt::lookupId(const QString &str)
QString StringToInt::lookupString(int idx)
{
- QReadLocker readLocker(&readLock);
- if (Q_LIKELY(StringToInt::m_stringsArray.size() > idx))
- return StringToInt::m_stringsArray.at(idx);
-
- // Maybe it's in the pending array then
- QMutexLocker lock(&mutex);
- if (StringToInt::m_stringsArray.size() + StringToInt::m_pendingStringsArray.size() > idx)
- return StringToInt::m_pendingStringsArray.at(idx - StringToInt::m_stringsArray.size());
+ QReadLocker readLocker(&lock);
+ if (Q_LIKELY(reverseMap.size() > idx))
+ return reverseMap.at(idx);
return QString();
}
diff --git a/src/render/backend/stringtoint_p.h b/src/render/backend/stringtoint_p.h
index 2d9e566fb..996cecf33 100644
--- a/src/render/backend/stringtoint_p.h
+++ b/src/render/backend/stringtoint_p.h
@@ -67,11 +67,6 @@ public:
static int lookupId(const QString &str);
static int lookupId(QLatin1String str);
static QString lookupString(int idx);
-
-private:
- static QVector<QString> m_stringsArray;
- static QVector<QString> m_pendingStringsArray;
- static int m_calls;
};
} // Render