From 9aeacb07b1169fa3dc9b7653e8f30070a91569d5 Mon Sep 17 00:00:00 2001 From: Milian Wolff Date: Thu, 19 Jun 2014 12:21:41 +0200 Subject: 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. --- src/core/bufferfragment_p.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'src/core/bufferfragment_p.h') 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(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 -- cgit v1.2.1