QTZ/Darwin: Make available-ID checks cheaper

Previously we've checked whether an ID is available by computing the
full list of all known available IDs (converting each from NSString to
QBA in the process) in order to compare the offered ID to each of
those in turn. This is a significant performance bottle-neck

Simply trying to construct the NSTimeZone instance should suffice to
determine whether there is such a zone; if the ID is not available, we
apparently get back a null pointer, which is easy enough to test for.

Pick-to: 6.6 6.5
Fixes: QTBUG-118759
Change-Id: Ib272c96e25db9640490299c638e2e9196a58712f
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
Edward Welbourne 2023-11-03 11:51:20 +01:00
parent c88211d1e4
commit be55fbede9
2 changed files with 11 additions and 7 deletions

View File

@ -57,12 +57,10 @@ QMacTimeZonePrivate *QMacTimeZonePrivate::clone() const
void QMacTimeZonePrivate::init(const QByteArray &ianaId) void QMacTimeZonePrivate::init(const QByteArray &ianaId)
{ {
if (availableTimeZoneIds().contains(ianaId)) {
m_nstz = [[NSTimeZone timeZoneWithName:QString::fromUtf8(ianaId).toNSString()] retain]; m_nstz = [[NSTimeZone timeZoneWithName:QString::fromUtf8(ianaId).toNSString()] retain];
if (m_nstz) if (m_nstz) {
m_id = ianaId; m_id = ianaId;
} } else {
if (!m_nstz) {
// macOS has been seen returning a systemTimeZone which reports its name // macOS has been seen returning a systemTimeZone which reports its name
// as Asia/Kolkata, which doesn't appear in knownTimeZoneNames (which // as Asia/Kolkata, which doesn't appear in knownTimeZoneNames (which
// calls the zone Asia/Calcutta). So explicitly check for the name // calls the zone Asia/Calcutta). So explicitly check for the name
@ -286,6 +284,12 @@ QByteArray QMacTimeZonePrivate::systemTimeZoneId() const
return QString::fromNSString(NSTimeZone.systemTimeZone.name).toUtf8(); return QString::fromNSString(NSTimeZone.systemTimeZone.name).toUtf8();
} }
bool QMacTimeZonePrivate::isTimeZoneIdAvailable(const QByteArray& ianaId) const
{
QMacAutoReleasePool pool;
return [NSTimeZone timeZoneWithName:QString::fromUtf8(ianaId).toNSString()] != nil;
}
QList<QByteArray> QMacTimeZonePrivate::availableTimeZoneIds() const QList<QByteArray> QMacTimeZonePrivate::availableTimeZoneIds() const
{ {
NSEnumerator *enumerator = NSTimeZone.knownTimeZoneNames.objectEnumerator; NSEnumerator *enumerator = NSTimeZone.knownTimeZoneNames.objectEnumerator;

View File

@ -366,7 +366,7 @@ public:
Data previousTransition(qint64 beforeMSecsSinceEpoch) const override; Data previousTransition(qint64 beforeMSecsSinceEpoch) const override;
QByteArray systemTimeZoneId() const override; QByteArray systemTimeZoneId() const override;
bool isTimeZoneIdAvailable(const QByteArray &ianaId) const override;
QList<QByteArray> availableTimeZoneIds() const override; QList<QByteArray> availableTimeZoneIds() const override;
NSTimeZone *nsTimeZone() const; NSTimeZone *nsTimeZone() const;