diff options
author | Milian Wolff <mail@milianw.de> | 2014-06-19 12:21:41 +0200 |
---|---|---|
committer | Milian Wolff <mail@milianw.de> | 2014-06-19 12:21:41 +0200 |
commit | 9aeacb07b1169fa3dc9b7653e8f30070a91569d5 (patch) | |
tree | 711b513326fb9c459a8b9a6fb7e64517e2022351 /src/core/bufferfragment_p.h | |
parent | 9a5d6523689067a9cde717a8f375d4eca246b119 (diff) | |
download | kconfig-9aeacb07b1169fa3dc9b7653e8f30070a91569d5.tar.gz kconfig-9aeacb07b1169fa3dc9b7653e8f30070a91569d5.tar.bz2 |
Optimize KConfigIniBackend::parseConfig by reducing allocations.
Yet another awesome application of the Qt implicit sharing trick.
Since config files often contain only few different keys and even
value strings, we can share them. This reduces memory consumption
and also speeds up parsing, as we do not have to allocate the
duplicated strings, but can simply reuse the previous values.
The most extreme case for this of my knowledge, is KatePart:
katesyntaxhighlightingrc has more than 20k lines which triggered
nearly 30k allocations on startup. With this patch applied, this
value goes down dramatically. I added a simple static counter for
the cache hit/miss ratio, which resulted in 5442 cache misses compared
to 43624 cache hits across all KConfig files parsed by kwrite.
REVIEW: 118587
This is a forward-port of b8aaeff128233cfaecf67899168887572589dde8.
Diffstat (limited to 'src/core/bufferfragment_p.h')
-rw-r--r-- | src/core/bufferfragment_p.h | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/src/core/bufferfragment_p.h b/src/core/bufferfragment_p.h index e2154a59..a86e2922 100644 --- a/src/core/bufferfragment_p.h +++ b/src/core/bufferfragment_p.h @@ -150,6 +150,11 @@ public: return (other.size() != (int)len || memcmp(d, other.constData(), len) != 0); } + bool operator==(const BufferFragment &other) const + { + return other.len == len && !memcmp(d, other.d, len); + } + int indexOf(char c, unsigned int from = 0) const { const char *cursor = d + from - 1; @@ -190,4 +195,21 @@ private: unsigned int len; }; +uint qHash(const KConfigIniBackend::BufferFragment &fragment) +{ + const uchar *p = reinterpret_cast<const uchar*>(fragment.constData()); + const int len = fragment.length(); + + // This algorithm is copied from qhash.cpp (Qt5 version). + // Sadly this code is not accessible from the outside without going through abstraction + // layers. Even QByteArray::fromRawData would do an allocation internally... + uint h = 0; + + for (int i = 0; i < len; ++i) { + h = 31 * h + p[i]; + } + + return h; +} + #endif |