summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2020-09-21 11:06:18 +0200
committerThiago Macieira <thiago.macieira@intel.com>2020-09-23 14:59:08 +0000
commit3bd6901429611636d254bb0140799b019112985d (patch)
treed11ae361d1d8c019cd7a0ccf1e996c74bb50ad14 /src
parent691762e0e36558257291677d3458628558b380f5 (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.cpp35
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