diff options
author | Robin Burchell <robin.burchell@crimson.no> | 2019-05-03 20:02:10 +0200 |
---|---|---|
committer | Edward Welbourne <edward.welbourne@qt.io> | 2020-03-20 16:58:09 +0200 |
commit | 2af04860f6536bbbf82ee21d6aa95ca33a60fbf5 (patch) | |
tree | b5388ea57e36cccc6a2f50acd5013681bd6b019f /src/corelib/time/qtimezoneprivate_p.h | |
parent | d535dfea1f2d801268396f328c5c99968ff164ec (diff) |
qtimezoneprivate_tz: Apply a cache over the top of timezone data
Constantly re-reading the timezone information only to be told the exact
same thing is wildly expensive, which can hurt in operations that cause
a lot of QTimeZone creation, for example, V4's DateObject - which
creates them a lot (in DaylightSavingTA).
This performance problem was identified when I noticed that a
QDateTime binding updated once per frame was causing >100% CPU usage
(on a desktop!) thanks to a QtQuickControls 1 Calendar (which has a
number of bindings to the date's properties like getMonth() and so
on).
The newly added tst_QTimeZone::systemTimeZone benchmark gets a ~90%
decrease in instruction count:
--- before
+++ after
PASS : tst_QTimeZone::systemTimeZone()
RESULT : tst_QTimeZone::systemTimeZone():
- 0.024 msecs per iteration (total: 51, iterations: 2048)
+ 0.0036 msecs per iteration (total: 59, iterations: 16384)
Also impacted (over in QDateTime) is
tst_QDateTime::setMSecsSinceEpochTz(). The results here are - on the
surface - less impressive (~0.17% drop), however, it isn't even
creating QTimeZone on a hot path to begin with, so a large drop would
have been a surprise.
Added several further benchmarks to cover non-system zones and
traverse transitions.
Done-With: Edward Welbourne <edward.welbourne@qt.io>
Task-number: QTBUG-75585
Change-Id: I044a84fc2d3a2dc965f63cd3a3299fc509750bf7
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/corelib/time/qtimezoneprivate_p.h')
-rw-r--r-- | src/corelib/time/qtimezoneprivate_p.h | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/src/corelib/time/qtimezoneprivate_p.h b/src/corelib/time/qtimezoneprivate_p.h index 5f6491ef81..c3e9064b8c 100644 --- a/src/corelib/time/qtimezoneprivate_p.h +++ b/src/corelib/time/qtimezoneprivate_p.h @@ -287,6 +287,16 @@ Q_DECL_CONSTEXPR inline bool operator==(const QTzTransitionRule &lhs, const QTzT Q_DECL_CONSTEXPR inline bool operator!=(const QTzTransitionRule &lhs, const QTzTransitionRule &rhs) noexcept { return !operator==(lhs, rhs); } +// These are stored separately from QTzTimeZonePrivate so that they can be +// cached, avoiding the need to re-parse them from disk constantly. +struct QTzTimeZoneCacheEntry +{ + QVector<QTzTransitionTime> m_tranTimes; + QVector<QTzTransitionRule> m_tranRules; + QList<QByteArray> m_abbreviations; + QByteArray m_posixRule; +}; + class Q_AUTOTEST_EXPORT QTzTimeZonePrivate final : public QTimeZonePrivate { QTzTimeZonePrivate(const QTzTimeZonePrivate &) = default; @@ -334,13 +344,11 @@ private: QVector<QTimeZonePrivate::Data> getPosixTransitions(qint64 msNear) const; Data dataForTzTransition(QTzTransitionTime tran) const; - QVector<QTzTransitionTime> m_tranTimes; - QVector<QTzTransitionRule> m_tranRules; - QList<QByteArray> m_abbreviations; #if QT_CONFIG(icu) mutable QSharedDataPointer<QTimeZonePrivate> m_icu; #endif - QByteArray m_posixRule; + QTzTimeZoneCacheEntry cached_data; + QVector<QTzTransitionTime> tranCache() const { return cached_data.m_tranTimes; } }; #endif // Q_OS_UNIX |