diff options
author | Marc Mutz <marc.mutz@kdab.com> | 2016-05-17 13:05:26 +0200 |
---|---|---|
committer | Marc Mutz <marc.mutz@kdab.com> | 2019-05-29 22:55:54 +0200 |
commit | dd1d8f51e67ec93031fdd7f7930d63761d1238e6 (patch) | |
tree | ae83b2c6beaa5dfbc9e3cbcb5af5c12eeb1519ae /tools | |
parent | 79aa74b5d9df52605a8833e3853b422ca8e7a651 (diff) |
qgltf: replace QHash with a C array
The keys are statically known, short, and few, so
replace the QHash<QByteArray, OpenMode> with a C
array of a {char[2]; OpenMode} struct, which
occupies just 40B in read-only memory. We don't
even need to sort the list, as binary search
in a list of ten entries is slower than linear
search (five comparisons each, on average, with
the linear scan having a predictable memory
access pattern.
Saves ~2.5KiB in text size on optimized GCC 6.0
Linux AMD64 builds.
Change-Id: I8ac680dc3a5c3489438d7dd9077aac46cd5708ab
Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/qgltf/qgltf.cpp | 51 |
1 files changed, 29 insertions, 22 deletions
diff --git a/tools/qgltf/qgltf.cpp b/tools/qgltf/qgltf.cpp index 3cbe6f3d2..562e50911 100644 --- a/tools/qgltf/qgltf.cpp +++ b/tools/qgltf/qgltf.cpp @@ -83,14 +83,10 @@ private: class AssimpIOSystem : public Assimp::IOSystem { public: - AssimpIOSystem(); bool Exists(const char *pFile) const override; char getOsSeparator() const override; Assimp::IOStream *Open(const char *pFile, const char *pMode) override; void Close(Assimp::IOStream *pFile) override; - -private: - QHash<QByteArray, QIODevice::OpenMode> m_openModeMap; }; AssimpIOStream::AssimpIOStream(QIODevice *device) : @@ -151,18 +147,29 @@ void AssimpIOStream::Flush() // we don't write via assimp } -AssimpIOSystem::AssimpIOSystem() -{ - m_openModeMap[QByteArrayLiteral("r")] = QIODevice::ReadOnly; - m_openModeMap[QByteArrayLiteral("r+")] = QIODevice::ReadWrite; - m_openModeMap[QByteArrayLiteral("w")] = QIODevice::WriteOnly | QIODevice::Truncate; - m_openModeMap[QByteArrayLiteral("w+")] = QIODevice::ReadWrite | QIODevice::Truncate; - m_openModeMap[QByteArrayLiteral("a")] = QIODevice::WriteOnly | QIODevice::Append; - m_openModeMap[QByteArrayLiteral("a+")] = QIODevice::ReadWrite | QIODevice::Append; - m_openModeMap[QByteArrayLiteral("wb")] = QIODevice::WriteOnly; - m_openModeMap[QByteArrayLiteral("wt")] = QIODevice::WriteOnly | QIODevice::Text; - m_openModeMap[QByteArrayLiteral("rb")] = QIODevice::ReadOnly; - m_openModeMap[QByteArrayLiteral("rt")] = QIODevice::ReadOnly | QIODevice::Text; +static QIODevice::OpenMode openModeFromText(const char *name) noexcept +{ + static const struct OpenModeMapping { + char name[2]; + ushort mode; + } openModeMapping[] = { + { { 'r', 0 }, QIODevice::ReadOnly }, + { { 'r', '+' }, QIODevice::ReadWrite }, + { { 'w', 0 }, QIODevice::WriteOnly | QIODevice::Truncate }, + { { 'w', '+' }, QIODevice::ReadWrite | QIODevice::Truncate }, + { { 'a', 0 }, QIODevice::WriteOnly | QIODevice::Append }, + { { 'a', '+' }, QIODevice::ReadWrite | QIODevice::Append }, + { { 'w', 'b' }, QIODevice::WriteOnly }, + { { 'w', 't' }, QIODevice::WriteOnly | QIODevice::Text }, + { { 'r', 'b' }, QIODevice::ReadOnly }, + { { 'r', 't' }, QIODevice::ReadOnly | QIODevice::Text }, + }; + + for (auto e : openModeMapping) { + if (qstrncmp(e.name, name, sizeof(OpenModeMapping::name)) == 0) + return static_cast<QIODevice::OpenMode>(e.mode); + } + return QIODevice::NotOpen; } bool AssimpIOSystem::Exists(const char *pFile) const @@ -178,13 +185,13 @@ char AssimpIOSystem::getOsSeparator() const Assimp::IOStream *AssimpIOSystem::Open(const char *pFile, const char *pMode) { const QString fileName(QString::fromUtf8(pFile)); - const QByteArray cleanedMode(QByteArray(pMode).trimmed()); + const QLatin1String cleanedMode = QLatin1String{pMode}.trimmed(); - const QIODevice::OpenMode openMode = m_openModeMap.value(cleanedMode, QIODevice::NotOpen); - - QScopedPointer<QFile> file(new QFile(fileName)); - if (file->open(openMode)) - return new AssimpIOStream(file.take()); + if (const QIODevice::OpenMode openMode = openModeFromText(cleanedMode.data())) { + QScopedPointer<QFile> file(new QFile(fileName)); + if (file->open(openMode)) + return new AssimpIOStream(file.take()); + } return nullptr; } |