From d3ede38eddf94b24d195ed58e13182117d7e2b74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 5 May 2023 12:27:33 +0200 Subject: [PATCH] Darwin: Cache system locale's zero digit and invalidate on locale changes As part of ed2b110b6add650954dc102a0317c14ff826c677 the implicit caching of some of the system locale queries was removed, resulting in a three orders of magnitude performance regression on converting dates to strings via QLocale::system() on macOS and iOS. We now cache the most critical of these, the zero digit, in the Darwin backend, and clear the cache in response to the system locale changing, restoring the performance two orders of a magnitude closer to that of Qt 5. We're still one order of magnitude off, which seems to stem from the auto release pool in QSystemLocale::query(). Fixes: QTBUG-104785 Pick-to: 6.5 6.2 Change-Id: I26f96147d430f08a721c55a1048d586a4af3a76c Reviewed-by: Edward Welbourne --- src/corelib/text/qlocale_mac.mm | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/corelib/text/qlocale_mac.mm b/src/corelib/text/qlocale_mac.mm index 1aafacba33..9a25bee0de 100644 --- a/src/corelib/text/qlocale_mac.mm +++ b/src/corelib/text/qlocale_mac.mm @@ -154,14 +154,26 @@ static QVariant macDayName(int day, QSystemLocale::QueryType type) static QString macZeroDigit() { - QCFType locale = CFLocaleCopyCurrent(); - QCFType numberFormatter = - CFNumberFormatterCreate(nullptr, locale, kCFNumberFormatterNoStyle); - const int zeroDigit = 0; - QCFType value - = CFNumberFormatterCreateStringWithValue(nullptr, numberFormatter, - kCFNumberIntType, &zeroDigit); - return QString::fromCFString(value); + static QString cachedZeroDigit; + + if (cachedZeroDigit.isNull()) { + QCFType locale = CFLocaleCopyCurrent(); + QCFType numberFormatter = + CFNumberFormatterCreate(nullptr, locale, kCFNumberFormatterNoStyle); + const int zeroDigit = 0; + QCFType value + = CFNumberFormatterCreateStringWithValue(nullptr, numberFormatter, + kCFNumberIntType, &zeroDigit); + cachedZeroDigit = QString::fromCFString(value); + } + + static QMacNotificationObserver localeChangeObserver = QMacNotificationObserver( + nil, NSCurrentLocaleDidChangeNotification, [&] { + qCDebug(lcLocale) << "System locale changed"; + cachedZeroDigit = QString(); + }); + + return cachedZeroDigit; } static QString zeroPad(QString &&number, qsizetype minDigits, const QString &zero)