diff options
author | Edward Welbourne <edward.welbourne@qt.io> | 2020-09-21 11:06:18 +0200 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2020-09-23 14:59:08 +0000 |
commit | 3bd6901429611636d254bb0140799b019112985d (patch) | |
tree | d11ae361d1d8c019cd7a0ccf1e996c74bb50ad14 /src | |
parent | 691762e0e36558257291677d3458628558b380f5 (diff) |
Use same-msecs optimization more in QDateTime comparison
QDateTime's comparisons just compare milliseconds when both values are
local times and their statuses (hence DST-ness) match. It can do the
same for time-zones. While doing the same for UTC and fixed offsets
wins nothing, it also costs nothing, given that we're already checking
the spec.
Task-number: QTBUG-75585
Change-Id: Ib6d824569aba8def2f1319ef3a11cca6869a5b5e
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/time/qdatetime.cpp | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/src/corelib/time/qdatetime.cpp b/src/corelib/time/qdatetime.cpp index f51411f45b..c6a41855b0 100644 --- a/src/corelib/time/qdatetime.cpp +++ b/src/corelib/time/qdatetime.cpp @@ -2763,6 +2763,37 @@ static inline Qt::TimeSpec getSpec(const QDateTimeData &d) return extractSpec(getStatus(d)); } +/* True if we *can cheaply determine* that a and b use the same offset. + If they use different offsets or it would be expensive to find out, false. + Calls to toMSecsSinceEpoch() are expensive, for these purposes. + See QDateTime's comparison operators. +*/ +static inline bool usesSameOffset(const QDateTimeData &a, const QDateTimeData &b) +{ + const auto status = getStatus(a); + if (status != getStatus(b)) + return false; + // Status includes DST-ness, so we now know they match in it. + + switch (extractSpec(status)) { + case Qt::LocalTime: + case Qt::UTC: + return true; + + case Qt::TimeZone: + /* TimeZone always determines its offset during construction of the + private data. Even if we're in different zones, what matters is the + offset actually in effect at the specific time. (DST can cause things + with the same time-zone to use different offsets, but we already + checked their DSTs match.) */ + case Qt::OffsetFromUTC: // always knows its offset, which is all that matters. + Q_ASSERT(!a.isShort() && !b.isShort()); + return a->m_offsetFromUtc == b->m_offsetFromUtc; + } + Q_UNREACHABLE(); + return false; +} + #if QT_CONFIG(timezone) void QDateTimePrivate::setUtcOffsetByTZ(qint64 atMSecsSinceEpoch) { @@ -4333,7 +4364,7 @@ bool QDateTime::operator==(const QDateTime &other) const if (!other.isValid()) return false; - if (getSpec(d) == Qt::LocalTime && getStatus(d) == getStatus(other.d)) + if (usesSameOffset(d, other.d)) return getMSecs(d) == getMSecs(other.d); // Convert to UTC and compare @@ -4365,7 +4396,7 @@ bool QDateTime::operator<(const QDateTime &other) const if (!other.isValid()) return false; - if (getSpec(d) == Qt::LocalTime && getStatus(d) == getStatus(other.d)) + if (usesSameOffset(d, other.d)) return getMSecs(d) < getMSecs(other.d); // Convert to UTC and compare |