Optimize QUtcTimeZonePrivate common case for UTC id/name

When the name/id is "UTC" then we can reuse the interned
string literals, which allows us to get rid of extra memory
allocations (and frees later on) for these strings.

This patch brings another hefty relative improvement to my benchmark.
Compare the following results for tst_QTimeZone::utc benchmark as
built on my machine with:

    Config: Using QtTest library 6.10.0, Qt 6.10.0 (x86_64-little_endian-lp64 shared (dynamic) release build; by GCC 14.2.1 20250207), arch unknown

Before:

    102.004937 nsecs per iteration (total: 102,004,835, iterations: 999999)
    452.836869 CPU cycles per iteration, 4,44 GHz (total: 452,836,417, iterations: 999999)
    1,182.801068 instructions per iteration, 2,612 instr/cycle (total: 1,182,799,886, iterations: 999999)
    267.143901 branch instructions per iteration, 2,62 G/sec (total: 267,143,634, iterations: 999999)

After:

    36.708812 nsecs per iteration (total: 36,708,776, iterations: 999999)
    169.024518 CPU cycles per iteration, 4,6 GHz (total: 169,024,349, iterations: 999999)
    601.286607 instructions per iteration, 3,557 instr/cycle (total: 601,286,006, iterations: 999999)
    139.051610 branch instructions per iteration, 3,79 G/sec (total: 139,051,471, iterations: 999999)

Relative Delta:

            before   after    improvement
    nsecs   102.0    36.7     2.78x
    cycles  452.8    169.0    2.68x
    instr.  1182.8   601.3    1.97x
    branch  276.1    139.1    1.98x

Pick-to: 6.8
Change-Id: I4aae3ac59edc173f96751d7e05335ad6b63f7275
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
(cherry picked from commit c67659149f7f3a4600a211e82bfd067a8e08ae51)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Milian Wolff 2025-02-22 15:49:45 +01:00 committed by Qt Cherry-pick Bot
parent 22e66638a6
commit 0437f1925b

View File

@ -979,8 +979,16 @@ QUtcTimeZonePrivate::QUtcTimeZonePrivate(qint32 offsetSeconds)
if (data != std::end(utcDataTable) && data->offsetFromUtc == offsetSeconds) {
QByteArrayView ianaId = data->id();
qsizetype cut = ianaId.indexOf(' ');
id = (cut < 0 ? ianaId : ianaId.first(cut)).toByteArray();
name = QString::fromUtf8(id);
QByteArrayView cutId = (cut < 0 ? ianaId : ianaId.first(cut));
if (cutId == utcQByteArray()) {
// optimize: reuse interned strings for the common case
id = utcQByteArray();
name = utcQString();
} else {
// fallback to allocate new strings otherwise
id = cutId.toByteArray();
name = QString::fromUtf8(id);
}
Q_ASSERT(!name.isEmpty());
} else { // Fall back to a UTC-offset name:
name = isoOffsetFormat(offsetSeconds, QTimeZone::ShortName);