From 3bd6901429611636d254bb0140799b019112985d Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 21 Sep 2020 11:06:18 +0200 Subject: 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 --- src/corelib/time/qdatetime.cpp | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) (limited to 'src') 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 -- cgit v1.2.3