From 9b849eea41b0f072b2b20430fbaeef7df9dff176 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 6 Mar 2025 18:04:03 +0100 Subject: [PATCH] QTimeZone: return a shared copy from utc() The UTC time-zone never changes, not even under a locale change, so memoize utc() using a Q_GLOBAL_STATIC cache. Check its isDestroyed() and fall back to the current implementation in that case. This keeps the function available even in late shutdown stages. _This_ is a knife^Woptimization: PASS : tst_QTimeZone::utc() RESULT : tst_QTimeZone::utc(): - 33.1472430 nsecs per iteration (total: 331,472,431, iterations: 10000000) + 12.8953219 nsecs per iteration (total: 128,953,219, iterations: 10000000) - 150.5929452 CPU cycles per iteration, 4,54 GHz (total: 1,505,929,452, iterations: 10000000) + 60.3382987 CPU cycles per iteration, 4,68 GHz (total: 603,382,988, iterations: 10000000) - 396.0402927 instructions per iteration, 2,630 instr/cycle (total: 3,960,402,928, iterations: 10000000) + 84.0138436 instructions per iteration, 1,392 instr/cycle (total: 840,138,437, iterations: 10000000) - 96.0069811 branch instructions per iteration, 2,9 G/sec (total: 960,069,811, iterations: 10000000) + 28.0024131 branch instructions per iteration, 2,17 G/sec (total: 280,024,132, iterations: 10000000) Amends HEAD^. Change-Id: I4496f3a4c1f64b0615930337662bcd04af0a2ade Reviewed-by: Thiago Macieira Reviewed-by: Milian Wolff Reviewed-by: Edward Welbourne --- src/corelib/time/qtimezone.cpp | 12 +++++++++++- src/corelib/time/qtimezoneprivate_p.h | 2 ++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/corelib/time/qtimezone.cpp b/src/corelib/time/qtimezone.cpp index 1da2e037c70..421c2d68786 100644 --- a/src/corelib/time/qtimezone.cpp +++ b/src/corelib/time/qtimezone.cpp @@ -1443,6 +1443,7 @@ QTimeZone QTimeZone::systemTimeZone() } /*! + \fn QTimeZone QTimeZone::utc() \since 5.5 Returns a QTimeZone object that describes UTC as a time zone. @@ -1453,11 +1454,20 @@ QTimeZone QTimeZone::systemTimeZone() \sa systemTimeZone(), Initialization, asBackendZone() */ -QTimeZone QTimeZone::utc() +QTimeZone QTimeZonePrivate::utcQTimeZone() { return QTimeZone(*new QUtcTimeZonePrivate()); } +Q_GLOBAL_STATIC(QTimeZone, utcTimeZone, QTimeZonePrivate::utcQTimeZone()); + +QTimeZone QTimeZone::utc() +{ + if (Q_UNLIKELY(utcTimeZone.isDestroyed())) + return QTimeZonePrivate::utcQTimeZone(); // create a new, unshared one + return *utcTimeZone; // take a shallow copy +} + /*! Returns \c true if a given time zone \a ianaId is available on this system. diff --git a/src/corelib/time/qtimezoneprivate_p.h b/src/corelib/time/qtimezoneprivate_p.h index d240beb2efa..b2c03e49f0a 100644 --- a/src/corelib/time/qtimezoneprivate_p.h +++ b/src/corelib/time/qtimezoneprivate_p.h @@ -161,6 +161,8 @@ public: return QByteArrayLiteral("UTC"); } + [[nodiscard]] static QTimeZone utcQTimeZone(); + protected: // Zones CLDR data says match a condition. // Use to filter what the backend has available.