From b9c55b5b9e983e446695f471aed1cdf14e14c88e Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 18 Jan 2022 22:02:20 +0100 Subject: [PATCH] QVersionNumber: de-inline QList constructor calls and resize() The QList range ctor and other QList methods have percolated up near the top of the list of Clang -ftime-trace most expensive template instantiations in PCH libQt6Gui.so builds: **** Templates that took longest to instantiate: [...] 5138 ms: QList::QList (256 times, avg 20 ms) 4327 ms: QtPrivate::QCommonArrayOps::appendIteratorRange (256 times, avg 16 ms) The code in 6.3 is already sufficiently different for this patch to not be applicable there. Task-number: QTBUG-97601 Change-Id: I4420c8c90e472ecfd679b414cc4334d2ab55cce3 Reviewed-by: Fabian Kosmale Reviewed-by: Thiago Macieira --- src/corelib/tools/qversionnumber.cpp | 23 +++++++++++++++++++++++ src/corelib/tools/qversionnumber.h | 25 +++++++++++++------------ 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/src/corelib/tools/qversionnumber.cpp b/src/corelib/tools/qversionnumber.cpp index 6494603a11e..8002cc9d3f7 100644 --- a/src/corelib/tools/qversionnumber.cpp +++ b/src/corelib/tools/qversionnumber.cpp @@ -481,6 +481,29 @@ QVersionNumber QVersionNumber::fromString(QAnyStringView string, qsizetype *suff return string.visit([=] (auto string) { return from_string(string, suffixIndex); }); } +void QVersionNumber::SegmentStorage::setListData(const QList &seg) +{ + pointer_segments = new QList(seg); +} + +void QVersionNumber::SegmentStorage::setListData(QList &&seg) +{ + pointer_segments = new QList(std::move(seg)); +} + +void QVersionNumber::SegmentStorage::setListData(const int *first, const int *last) +{ + pointer_segments = new QList(first, last); +} + +void QVersionNumber::SegmentStorage::resize(qsizetype len) +{ + if (isUsingPointer()) + pointer_segments->resize(len); + else + setInlineSize(len); +} + void QVersionNumber::SegmentStorage::setVector(int len, int maj, int min, int mic) { pointer_segments = new QList; diff --git a/src/corelib/tools/qversionnumber.h b/src/corelib/tools/qversionnumber.h index c00587c300e..e023810b403 100644 --- a/src/corelib/tools/qversionnumber.h +++ b/src/corelib/tools/qversionnumber.h @@ -96,13 +96,15 @@ class QVersionNumber if (dataFitsInline(seg.data(), seg.size())) setInlineData(seg.data(), seg.size()); else - pointer_segments = new QList(seg); + setListData(seg); } + Q_CORE_EXPORT void setListData(const QList &seg); + SegmentStorage(const SegmentStorage &other) { if (other.isUsingPointer()) - pointer_segments = new QList(*other.pointer_segments); + setListData(*other.pointer_segments); else dummy = other.dummy; } @@ -112,7 +114,7 @@ class QVersionNumber if (isUsingPointer() && other.isUsingPointer()) { *pointer_segments = *other.pointer_segments; } else if (other.isUsingPointer()) { - pointer_segments = new QList(*other.pointer_segments); + setListData(*other.pointer_segments); } else { if (isUsingPointer()) delete pointer_segments; @@ -139,8 +141,11 @@ class QVersionNumber if (dataFitsInline(std::as_const(seg).data(), seg.size())) setInlineData(std::as_const(seg).data(), seg.size()); else - pointer_segments = new QList(std::move(seg)); + setListData(std::move(seg)); } + + Q_CORE_EXPORT void setListData(QList &&seg); + explicit SegmentStorage(std::initializer_list args) : SegmentStorage(args.begin(), args.end()) {} @@ -149,10 +154,12 @@ class QVersionNumber if (dataFitsInline(first, last - first)) { setInlineData(first, last - first); } else { - pointer_segments = new QList(first, last); + setListData(first, last); } } + Q_CORE_EXPORT void setListData(const int *first, const int *last); + ~SegmentStorage() { if (isUsingPointer()) delete pointer_segments; } bool isUsingPointer() const noexcept @@ -167,13 +174,7 @@ class QVersionNumber inline_segments[InlineSegmentMarker] = qint8(1 + 2 * len); } - void resize(qsizetype len) - { - if (isUsingPointer()) - pointer_segments->resize(len); - else - setInlineSize(len); - } + Q_CORE_EXPORT void resize(qsizetype len); int at(qsizetype index) const {