From 434c52269564c84e3ea57242b7aaa2fd7cad3f54 Mon Sep 17 00:00:00 2001 From: David Faure Date: Thu, 4 Aug 2016 10:01:21 +0200 Subject: [PATCH] Improve performance of QColor::name, now more than 4 times faster Before: HexRgb: 0.00230 ms per iteration, HexArgb: 0.00290 ms per iteration After: HexRgb: 0.00051 ms per iteration, HexArgb: 0.00061 ms per iteration This showed up as a relevant optimization when profiling KIconLoader which uses QColor::name() as part of the key -- thanks to Mark Gaiser for the investigation and first suggestion of a solution. I have also seen customer code writing a replacement for QColor::name() because it was too slow to be used as a hash key. Change-Id: I009ccdd712ea0d869d466e2c9894e0cea58f0e68 Reviewed-by: Marc Mutz --- src/gui/painting/qcolor.cpp | 5 +- tests/auto/gui/painting/qcolor/tst_qcolor.cpp | 2 + tests/benchmarks/gui/painting/painting.pro | 1 + .../benchmarks/gui/painting/qcolor/qcolor.pro | 7 ++ .../gui/painting/qcolor/tst_qcolor.cpp | 67 +++++++++++++++++++ 5 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 tests/benchmarks/gui/painting/qcolor/qcolor.pro create mode 100644 tests/benchmarks/gui/painting/qcolor/tst_qcolor.cpp diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp index 3f30c061dc1..d0a60f37041 100644 --- a/src/gui/painting/qcolor.cpp +++ b/src/gui/painting/qcolor.cpp @@ -521,9 +521,10 @@ QString QColor::name(NameFormat format) const { switch (format) { case HexRgb: - return QString::asprintf("#%02x%02x%02x", red(), green(), blue()); + return QLatin1Char('#') + QString::number(rgba() | 0x1000000, 16).rightRef(6); case HexArgb: - return QString::asprintf("#%02x%02x%02x%02x", alpha(), red(), green(), blue()); + // it's called rgba() but it does return AARRGGBB + return QLatin1Char('#') + QString::number(rgba() | 0x100000000, 16).rightRef(8); } return QString(); } diff --git a/tests/auto/gui/painting/qcolor/tst_qcolor.cpp b/tests/auto/gui/painting/qcolor/tst_qcolor.cpp index b81a4e2c4cc..289b06fc62f 100644 --- a/tests/auto/gui/painting/qcolor/tst_qcolor.cpp +++ b/tests/auto/gui/painting/qcolor/tst_qcolor.cpp @@ -284,6 +284,8 @@ void tst_QColor::name_data() QTest::newRow("global color darkMagenta") << QColor(Qt::darkMagenta) << "#800080" << QColor::HexRgb; QTest::newRow("global color darkYellow") << QColor(Qt::darkYellow) << "#808000" << QColor::HexRgb; QTest::newRow("transparent red") << QColor(255, 0, 0, 102) << "#66ff0000" << QColor::HexArgb; + QTest::newRow("fully_transparent_green_rgb") << QColor(0, 0, 255, 0) << "#0000ff" << QColor::HexRgb; + QTest::newRow("fully_transparent_green_argb") << QColor(0, 0, 255, 0) << "#000000ff" << QColor::HexArgb; } void tst_QColor::name() diff --git a/tests/benchmarks/gui/painting/painting.pro b/tests/benchmarks/gui/painting/painting.pro index 0eb7fa92a72..cdcfc9b3188 100644 --- a/tests/benchmarks/gui/painting/painting.pro +++ b/tests/benchmarks/gui/painting/painting.pro @@ -1,5 +1,6 @@ TEMPLATE = subdirs SUBDIRS = \ + qcolor \ qpainter \ qregion \ qtransform \ diff --git a/tests/benchmarks/gui/painting/qcolor/qcolor.pro b/tests/benchmarks/gui/painting/qcolor/qcolor.pro new file mode 100644 index 00000000000..5ceb7023234 --- /dev/null +++ b/tests/benchmarks/gui/painting/qcolor/qcolor.pro @@ -0,0 +1,7 @@ +QT += testlib +QT += gui-private + +TEMPLATE = app +TARGET = tst_bench_qcolor + +SOURCES += tst_qcolor.cpp diff --git a/tests/benchmarks/gui/painting/qcolor/tst_qcolor.cpp b/tests/benchmarks/gui/painting/qcolor/tst_qcolor.cpp new file mode 100644 index 00000000000..b67fa450d79 --- /dev/null +++ b/tests/benchmarks/gui/painting/qcolor/tst_qcolor.cpp @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author David Faure +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + + +class tst_QColor : public QObject +{ + Q_OBJECT + +private slots: + void nameRgb(); + void nameArgb(); +}; + +void tst_QColor::nameRgb() +{ + QColor color(128, 255, 10); + QCOMPARE(color.name(), QStringLiteral("#80ff0a")); + QBENCHMARK { + color.name(); + } +} + +void tst_QColor::nameArgb() +{ + QColor color(128, 255, 0, 102); + QCOMPARE(color.name(QColor::HexArgb), QStringLiteral("#6680ff00")); + QBENCHMARK { + color.name(QColor::HexArgb); + } +} + +QTEST_MAIN(tst_QColor) + +#include "tst_qcolor.moc"