From 349c0de0912884388f2490d4bfd6905424ccf194 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Tue, 20 Mar 2012 20:45:27 +0100 Subject: [PATCH] Significantly speed up insertion into QJsonObject/Array The code was only allocating memory for the next insertion leading to a reallocation of the whole data for every single insertion. The code now reserves some space and uses a decent growth strategy to avoid repeated reallocs. Change-Id: I48b0feab71ba8ca73e7037f8460080f198b2f009 Reviewed-by: Jamey Hicks --- src/corelib/json/qjson.cpp | 8 ------- src/corelib/json/qjson_p.h | 21 ++++++++++++++-- .../corelib/json/tst_bench_qtbinaryjson.cpp | 28 ++++++++++++++++++++++ 3 files changed, 47 insertions(+), 10 deletions(-) diff --git a/src/corelib/json/qjson.cpp b/src/corelib/json/qjson.cpp index 4f7372a..26f26b2 100644 --- a/src/corelib/json/qjson.cpp +++ b/src/corelib/json/qjson.cpp @@ -241,14 +241,6 @@ bool Entry::operator ==(const QString &key) const return (shallowKey() == key); } -bool Entry::operator >=(const QString &key) const -{ - if (value.latinKey) - return (shallowLatin1Key() >= key); - else - return (shallowKey() >= key); -} - bool Entry::operator ==(const Entry &other) const { if (value.latinKey) { diff --git a/src/corelib/json/qjson_p.h b/src/corelib/json/qjson_p.h index 0742ced..f8f41c2 100644 --- a/src/corelib/json/qjson_p.h +++ b/src/corelib/json/qjson_p.h @@ -620,15 +620,24 @@ public: bool operator ==(const QString &key) const; inline bool operator !=(const QString &key) const { return !operator ==(key); } - bool operator >=(const QString &key) const; + inline bool operator >=(const QString &key) const; bool operator ==(const Entry &other) const; bool operator >=(const Entry &other) const; }; +inline bool Entry::operator >=(const QString &key) const +{ + if (value.latinKey) + return (shallowLatin1Key() >= key); + else + return (shallowKey() >= key); +} + inline bool operator <(const QString &key, const Entry &e) { return e >= key; } + class Header { public: qle_uint tag; // 'qbjs' @@ -735,7 +744,15 @@ public: Data *clone(Base *b, int reserve = 0) { - int size = sizeof(Header) + b->size + reserve; + int size = sizeof(Header) + b->size; + if (ref.load() == 1 && alloc >= size + reserve) + return this; + + if (reserve) { + if (reserve < 128) + reserve = 128; + size = qMax(size + reserve, size *2); + } char *raw = (char *)malloc(size); Q_CHECK_PTR(raw); memcpy(raw + sizeof(Header), b, b->size); diff --git a/tests/benchmarks/corelib/json/tst_bench_qtbinaryjson.cpp b/tests/benchmarks/corelib/json/tst_bench_qtbinaryjson.cpp index e4e10ba..c6956b4 100644 --- a/tests/benchmarks/corelib/json/tst_bench_qtbinaryjson.cpp +++ b/tests/benchmarks/corelib/json/tst_bench_qtbinaryjson.cpp @@ -58,8 +58,12 @@ private Q_SLOTS: void parseNumbers(); void parseJson(); void parseJsonToVariant(); + void toByteArray(); void fromByteArray(); + + void jsonObjectInsert(); + void variantMapInsert(); }; BenchmarkQtBinaryJson::BenchmarkQtBinaryJson(QObject *parent) : QObject(parent) @@ -159,6 +163,30 @@ void BenchmarkQtBinaryJson::fromByteArray() } } +void BenchmarkQtBinaryJson::jsonObjectInsert() +{ + QJsonObject object; + QString test(QStringLiteral("testString")); + QJsonValue value(1.5); + + QBENCHMARK { + for (int i = 0; i < 1000; i++) + object.insert("testkey_" + i, value); + } +} + +void BenchmarkQtBinaryJson::variantMapInsert() +{ + QVariantMap object; + QString test(QStringLiteral("testString")); + QVariant variantValue(1.5); + + QBENCHMARK { + for (int i = 0; i < 1000; i++) + object.insert("testkey_" + i, variantValue); + } +} + QTEST_MAIN(BenchmarkQtBinaryJson) #include "tst_bench_qtbinaryjson.moc" -- 2.7.4