Darwin: Cache system locale's zero digit and invalidate on locale changes

As part of ed2b110b6a 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 <edward.welbourne@qt.io>
bb10
Tor Arne Vestbø 2023-05-05 12:27:33 +02:00
parent 74b377313e
commit d3ede38edd
1 changed files with 20 additions and 8 deletions

View File

@ -154,14 +154,26 @@ static QVariant macDayName(int day, QSystemLocale::QueryType type)
static QString macZeroDigit()
{
QCFType<CFLocaleRef> locale = CFLocaleCopyCurrent();
QCFType<CFNumberFormatterRef> numberFormatter =
CFNumberFormatterCreate(nullptr, locale, kCFNumberFormatterNoStyle);
const int zeroDigit = 0;
QCFType<CFStringRef> value
= CFNumberFormatterCreateStringWithValue(nullptr, numberFormatter,
kCFNumberIntType, &zeroDigit);
return QString::fromCFString(value);
static QString cachedZeroDigit;
if (cachedZeroDigit.isNull()) {
QCFType<CFLocaleRef> locale = CFLocaleCopyCurrent();
QCFType<CFNumberFormatterRef> numberFormatter =
CFNumberFormatterCreate(nullptr, locale, kCFNumberFormatterNoStyle);
const int zeroDigit = 0;
QCFType<CFStringRef> 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)