diff options
Diffstat (limited to 'tests/benchmarks/corelib/tools')
55 files changed, 1512 insertions, 1576 deletions
diff --git a/tests/benchmarks/corelib/tools/CMakeLists.txt b/tests/benchmarks/corelib/tools/CMakeLists.txt index c1b5cad1aa..b46eac4165 100644 --- a/tests/benchmarks/corelib/tools/CMakeLists.txt +++ b/tests/benchmarks/corelib/tools/CMakeLists.txt @@ -1,12 +1,16 @@ -# Generated from tools.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause add_subdirectory(containers-associative) add_subdirectory(containers-sequential) add_subdirectory(qcontiguouscache) add_subdirectory(qcryptographichash) +add_subdirectory(qhash) add_subdirectory(qlist) add_subdirectory(qmap) add_subdirectory(qrect) add_subdirectory(qringbuffer) +add_subdirectory(qset) +add_subdirectory(qsharedpointer) add_subdirectory(qstack) add_subdirectory(qvector) diff --git a/tests/benchmarks/corelib/tools/containers-associative/CMakeLists.txt b/tests/benchmarks/corelib/tools/containers-associative/CMakeLists.txt index d07794c25e..7036fa96b7 100644 --- a/tests/benchmarks/corelib/tools/containers-associative/CMakeLists.txt +++ b/tests/benchmarks/corelib/tools/containers-associative/CMakeLists.txt @@ -1,15 +1,13 @@ -# Generated from containers-associative.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### -## tst_bench_containers-associative Binary: +## tst_bench_containers_associative Binary: ##################################################################### -qt_add_benchmark(tst_bench_containers-associative +qt_internal_add_benchmark(tst_bench_containers_associative SOURCES - main.cpp - PUBLIC_LIBRARIES + tst_bench_containers_associative.cpp + LIBRARIES Qt::Test ) - -#### Keys ignored in scope 1:.:.:containers-associative.pro:<TRUE>: -# TEMPLATE = "app" diff --git a/tests/benchmarks/corelib/tools/containers-associative/containers-associative.pro b/tests/benchmarks/corelib/tools/containers-associative/containers-associative.pro deleted file mode 100644 index 89da01b02e..0000000000 --- a/tests/benchmarks/corelib/tools/containers-associative/containers-associative.pro +++ /dev/null @@ -1,6 +0,0 @@ -TEMPLATE = app -CONFIG += benchmark -QT = core testlib - -TARGET = tst_bench_containers-associative -SOURCES += main.cpp diff --git a/tests/benchmarks/corelib/tools/containers-associative/main.cpp b/tests/benchmarks/corelib/tools/containers-associative/tst_bench_containers_associative.cpp index 2f36bfda4f..a5618cfcaf 100644 --- a/tests/benchmarks/corelib/tools/containers-associative/main.cpp +++ b/tests/benchmarks/corelib/tools/containers-associative/tst_bench_containers_associative.cpp @@ -1,31 +1,8 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QString> +#include <QMap> +#include <QHash> #include <qtest.h> @@ -111,6 +88,7 @@ void testLookup(int size) val = container.value(i); } + Q_UNUSED(val); } void tst_associative_containers::lookup() @@ -126,4 +104,5 @@ void tst_associative_containers::lookup() } QTEST_MAIN(tst_associative_containers) -#include "main.moc" + +#include "tst_bench_containers_associative.moc" diff --git a/tests/benchmarks/corelib/tools/containers-sequential/CMakeLists.txt b/tests/benchmarks/corelib/tools/containers-sequential/CMakeLists.txt index 77e889160c..d24f26e664 100644 --- a/tests/benchmarks/corelib/tools/containers-sequential/CMakeLists.txt +++ b/tests/benchmarks/corelib/tools/containers-sequential/CMakeLists.txt @@ -1,15 +1,13 @@ -# Generated from containers-sequential.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## tst_bench_containers-sequential Binary: ##################################################################### -qt_add_benchmark(tst_bench_containers-sequential +qt_internal_add_benchmark(tst_bench_containers_sequential SOURCES - main.cpp - PUBLIC_LIBRARIES + tst_bench_containers_sequential.cpp + LIBRARIES Qt::Test ) - -#### Keys ignored in scope 1:.:.:containers-sequential.pro:<TRUE>: -# TEMPLATE = "app" diff --git a/tests/benchmarks/corelib/tools/containers-sequential/containers-sequential.pro b/tests/benchmarks/corelib/tools/containers-sequential/containers-sequential.pro deleted file mode 100644 index 509da95d22..0000000000 --- a/tests/benchmarks/corelib/tools/containers-sequential/containers-sequential.pro +++ /dev/null @@ -1,6 +0,0 @@ -TEMPLATE = app -CONFIG += benchmark -QT = core testlib - -TARGET = tst_bench_containers-sequential -SOURCES += main.cpp diff --git a/tests/benchmarks/corelib/tools/containers-sequential/main.cpp b/tests/benchmarks/corelib/tools/containers-sequential/tst_bench_containers_sequential.cpp index 6874c69abc..78c8016664 100644 --- a/tests/benchmarks/corelib/tools/containers-sequential/main.cpp +++ b/tests/benchmarks/corelib/tools/containers-sequential/tst_bench_containers_sequential.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only // This file contains benchmarks for comparing QList against std::vector #include <QtCore> @@ -55,21 +30,21 @@ T * f(T *ts) // dummy function to prevent code from being optimized away by the template<typename T> class UseCases_QList : public UseCases<T> { - void insert(int size) + void insert(int size) override { QList<T> v; - T t; + T t{}; QBENCHMARK { for (int i = 0; i < size; ++i) v.append(t); } } - void lookup(int size) + void lookup(int size) override { QList<T> v; - T t; + T t{}; for (int i = 0; i < size; ++i) v.append(t); @@ -87,21 +62,21 @@ class UseCases_QList : public UseCases<T> template <typename T> class UseCases_stdvector : public UseCases<T> { - void insert(int size) + void insert(int size) override { std::vector<T> v; - T t; + T t = {}; QBENCHMARK { for (int i = 0; i < size; ++i) v.push_back(t); } } - void lookup(int size) + void lookup(int size) override { std::vector<T> v; - T t; + T t = {}; for (int i = 0; i < size; ++i) v.push_back(t); @@ -244,4 +219,5 @@ void tst_vector_vs_std::lookup_Large() } QTEST_MAIN(tst_vector_vs_std) -#include "main.moc" + +#include "tst_bench_containers_sequential.moc" diff --git a/tests/benchmarks/corelib/tools/qchar/CMakeLists.txt b/tests/benchmarks/corelib/tools/qchar/CMakeLists.txt deleted file mode 100644 index c51e2a0059..0000000000 --- a/tests/benchmarks/corelib/tools/qchar/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -add_qt_test(tst_bench_qchar SOURCES main.cpp) diff --git a/tests/benchmarks/corelib/tools/qcontiguouscache/CMakeLists.txt b/tests/benchmarks/corelib/tools/qcontiguouscache/CMakeLists.txt index 8d4bff5979..9a68212fc0 100644 --- a/tests/benchmarks/corelib/tools/qcontiguouscache/CMakeLists.txt +++ b/tests/benchmarks/corelib/tools/qcontiguouscache/CMakeLists.txt @@ -1,12 +1,13 @@ -# Generated from qcontiguouscache.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## tst_bench_qcontiguouscache Binary: ##################################################################### -qt_add_benchmark(tst_bench_qcontiguouscache +qt_internal_add_benchmark(tst_bench_qcontiguouscache SOURCES - main.cpp - PUBLIC_LIBRARIES + tst_bench_qcontiguouscache.cpp + LIBRARIES Qt::Test ) diff --git a/tests/benchmarks/corelib/tools/qcontiguouscache/qcontiguouscache.pro b/tests/benchmarks/corelib/tools/qcontiguouscache/qcontiguouscache.pro deleted file mode 100644 index 59adad6bbc..0000000000 --- a/tests/benchmarks/corelib/tools/qcontiguouscache/qcontiguouscache.pro +++ /dev/null @@ -1,6 +0,0 @@ -CONFIG += benchmark -CONFIG += parallel_test -QT = core testlib - -TARGET = tst_bench_qcontiguouscache -SOURCES += main.cpp diff --git a/tests/benchmarks/corelib/tools/qcontiguouscache/main.cpp b/tests/benchmarks/corelib/tools/qcontiguouscache/tst_bench_qcontiguouscache.cpp index 368c8b66bb..ae2cf471b0 100644 --- a/tests/benchmarks/corelib/tools/qcontiguouscache/main.cpp +++ b/tests/benchmarks/corelib/tools/qcontiguouscache/tst_bench_qcontiguouscache.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QObject> #include <QTest> @@ -46,8 +21,6 @@ private slots: void contiguousCacheBenchmark(); }; -QTEST_MAIN(tst_QContiguousCache) - void tst_QContiguousCache::asScrollingList() { int i; @@ -176,4 +149,6 @@ void tst_QContiguousCache::contiguousCacheBenchmark() } } -#include "main.moc" +QTEST_MAIN(tst_QContiguousCache) + +#include "tst_bench_qcontiguouscache.moc" diff --git a/tests/benchmarks/corelib/tools/qcryptographichash/CMakeLists.txt b/tests/benchmarks/corelib/tools/qcryptographichash/CMakeLists.txt index 77168e443b..b69b884f7d 100644 --- a/tests/benchmarks/corelib/tools/qcryptographichash/CMakeLists.txt +++ b/tests/benchmarks/corelib/tools/qcryptographichash/CMakeLists.txt @@ -1,12 +1,13 @@ -# Generated from qcryptographichash.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## tst_bench_qcryptographichash Binary: ##################################################################### -qt_add_benchmark(tst_bench_qcryptographichash +qt_internal_add_benchmark(tst_bench_qcryptographichash SOURCES - main.cpp - PUBLIC_LIBRARIES + tst_bench_qcryptographichash.cpp + LIBRARIES Qt::Test ) diff --git a/tests/benchmarks/corelib/tools/qcryptographichash/main.cpp b/tests/benchmarks/corelib/tools/qcryptographichash/main.cpp deleted file mode 100644 index 1d414161d1..0000000000 --- a/tests/benchmarks/corelib/tools/qcryptographichash/main.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 Intel Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QByteArray> -#include <QCryptographicHash> -#include <QFile> -#include <QRandomGenerator> -#include <QString> -#include <QtTest> - -#include <time.h> - -class tst_bench_QCryptographicHash : public QObject -{ - Q_OBJECT - QByteArray blockOfData; - -public: - tst_bench_QCryptographicHash(); - -private Q_SLOTS: - void hash_data(); - void hash(); - void addData_data() { hash_data(); } - void addData(); - void addDataChunked_data() { hash_data(); } - void addDataChunked(); -}; - -const int MaxCryptoAlgorithm = QCryptographicHash::Sha3_512; -const int MaxBlockSize = 65536; - -const char *algoname(int i) -{ - switch (QCryptographicHash::Algorithm(i)) { - case QCryptographicHash::Md4: - return "md4-"; - case QCryptographicHash::Md5: - return "md5-"; - case QCryptographicHash::Sha1: - return "sha1-"; - case QCryptographicHash::Sha224: - return "sha2_224-"; - case QCryptographicHash::Sha256: - return "sha2_256-"; - case QCryptographicHash::Sha384: - return "sha2_384-"; - case QCryptographicHash::Sha512: - return "sha2_512-"; - case QCryptographicHash::Sha3_224: - return "sha3_224-"; - case QCryptographicHash::Sha3_256: - return "sha3_256-"; - case QCryptographicHash::Sha3_384: - return "sha3_384-"; - case QCryptographicHash::Sha3_512: - return "sha3_512-"; - case QCryptographicHash::Keccak_224: - return "keccak_224-"; - case QCryptographicHash::Keccak_256: - return "keccak_256-"; - case QCryptographicHash::Keccak_384: - return "keccak_384-"; - case QCryptographicHash::Keccak_512: - return "keccak_512-"; - } - Q_UNREACHABLE(); - return 0; -} - -tst_bench_QCryptographicHash::tst_bench_QCryptographicHash() - : blockOfData(MaxBlockSize, Qt::Uninitialized) -{ -#ifdef Q_OS_UNIX - QFile urandom("/dev/urandom"); - if (urandom.open(QIODevice::ReadOnly | QIODevice::Unbuffered)) { - QCOMPARE(urandom.read(blockOfData.data(), blockOfData.size()), qint64(MaxBlockSize)); - } else -#endif - { - for (int i = 0; i < MaxBlockSize; ++i) - blockOfData[i] = QRandomGenerator::global()->generate(); - } -} - -void tst_bench_QCryptographicHash::hash_data() -{ - QTest::addColumn<int>("algorithm"); - QTest::addColumn<QByteArray>("data"); - - static const int datasizes[] = { 0, 1, 64, 65, 512, 4095, 4096, 4097, 65536 }; - for (uint i = 0; i < sizeof(datasizes)/sizeof(datasizes[0]); ++i) { - Q_ASSERT(datasizes[i] < MaxBlockSize); - QByteArray data = QByteArray::fromRawData(blockOfData.constData(), datasizes[i]); - - for (int algo = QCryptographicHash::Md4; algo <= MaxCryptoAlgorithm; ++algo) - QTest::newRow(algoname(algo) + QByteArray::number(datasizes[i])) << algo << data; - } -} - -void tst_bench_QCryptographicHash::hash() -{ - QFETCH(int, algorithm); - QFETCH(QByteArray, data); - - QCryptographicHash::Algorithm algo = QCryptographicHash::Algorithm(algorithm); - QBENCHMARK { - QCryptographicHash::hash(data, algo); - } -} - -void tst_bench_QCryptographicHash::addData() -{ - QFETCH(int, algorithm); - QFETCH(QByteArray, data); - - QCryptographicHash::Algorithm algo = QCryptographicHash::Algorithm(algorithm); - QCryptographicHash hash(algo); - QBENCHMARK { - hash.reset(); - hash.addData(data); - hash.result(); - } -} - -void tst_bench_QCryptographicHash::addDataChunked() -{ - QFETCH(int, algorithm); - QFETCH(QByteArray, data); - - QCryptographicHash::Algorithm algo = QCryptographicHash::Algorithm(algorithm); - QCryptographicHash hash(algo); - QBENCHMARK { - hash.reset(); - - // add the data in chunks of 64 bytes - for (int i = 0; i < data.size() / 64; ++i) - hash.addData(data.constData() + 64 * i, 64); - hash.addData(data.constData() + data.size() / 64 * 64, data.size() % 64); - - hash.result(); - } -} - -QTEST_APPLESS_MAIN(tst_bench_QCryptographicHash) - -#include "main.moc" diff --git a/tests/benchmarks/corelib/tools/qcryptographichash/qcryptographichash.pro b/tests/benchmarks/corelib/tools/qcryptographichash/qcryptographichash.pro deleted file mode 100644 index 025c70c2d9..0000000000 --- a/tests/benchmarks/corelib/tools/qcryptographichash/qcryptographichash.pro +++ /dev/null @@ -1,6 +0,0 @@ -CONFIG += benchmark -CONFIG += cmdline -QT = core testlib - -TARGET = tst_bench_qcryptographichash -SOURCES += main.cpp diff --git a/tests/benchmarks/corelib/tools/qcryptographichash/tst_bench_qcryptographichash.cpp b/tests/benchmarks/corelib/tools/qcryptographichash/tst_bench_qcryptographichash.cpp new file mode 100644 index 0000000000..9f2d1c57f2 --- /dev/null +++ b/tests/benchmarks/corelib/tools/qcryptographichash/tst_bench_qcryptographichash.cpp @@ -0,0 +1,223 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// Copyright (C) 2017 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include <QByteArray> +#include <QCryptographicHash> +#include <QFile> +#include <QMetaEnum> +#include <QMessageAuthenticationCode> +#include <QRandomGenerator> +#include <QString> +#include <QTest> + +#include <qxpfunctional.h> +#include <numeric> + +#include <time.h> + +class tst_QCryptographicHash : public QObject +{ + Q_OBJECT + QByteArray blockOfData; + + using Algorithm = QCryptographicHash::Algorithm; + +public: + tst_QCryptographicHash(); + +private Q_SLOTS: + void hash_data(); + void hash(); + void addData_data() { hash_data(); } + void addData(); + void addDataChunked_data() { hash_data(); } + void addDataChunked(); + + // QMessageAuthenticationCode: + void hmac_hash_data() { hash_data(); } + void hmac_hash(); + void hmac_addData_data() { hash_data(); } + void hmac_addData(); + void hmac_setKey_data(); + void hmac_setKey(); +}; + +const int MaxBlockSize = 65536; + +static void for_each_algorithm(qxp::function_ref<void(QCryptographicHash::Algorithm, const char*) const> f) +{ + using A = QCryptographicHash::Algorithm; + static const auto metaEnum = QMetaEnum::fromType<A>(); + for (int i = 0, value = metaEnum.value(i); value != -1; value = metaEnum.value(++i)) + f(A(value), metaEnum.key(i)); +} + +tst_QCryptographicHash::tst_QCryptographicHash() + : blockOfData(MaxBlockSize, Qt::Uninitialized) +{ +#ifdef Q_OS_UNIX + QFile urandom("/dev/urandom"); + if (urandom.open(QIODevice::ReadOnly | QIODevice::Unbuffered)) { + QCOMPARE(urandom.read(blockOfData.data(), blockOfData.size()), qint64(MaxBlockSize)); + } else +#endif + { + for (int i = 0; i < MaxBlockSize; ++i) + blockOfData[i] = QRandomGenerator::global()->generate(); + } +} + +void tst_QCryptographicHash::hash_data() +{ + QTest::addColumn<Algorithm>("algo"); + QTest::addColumn<QByteArray>("data"); + + static const int datasizes[] = { 0, 1, 64, 65, 512, 4095, 4096, 4097, 65536 }; + for (uint i = 0; i < sizeof(datasizes)/sizeof(datasizes[0]); ++i) { + Q_ASSERT(datasizes[i] < MaxBlockSize); + QByteArray data = QByteArray::fromRawData(blockOfData.constData(), datasizes[i]); + + for_each_algorithm([&] (Algorithm algo, const char *name) { + if (algo == Algorithm::NumAlgorithms) + return; + QTest::addRow("%s-%d", name, datasizes[i]) << algo << data; + }); + } +} + +#define SKIP_IF_NOT_SUPPORTED(algo) do { \ + if (!QCryptographicHash::supportsAlgorithm(algo)) \ + QSKIP("This algorithm is not supported in this configuration"); \ + } while (false) \ + /* end */ + +void tst_QCryptographicHash::hash() +{ + QFETCH(const Algorithm, algo); + QFETCH(QByteArray, data); + + SKIP_IF_NOT_SUPPORTED(algo); + + QBENCHMARK { + [[maybe_unused]] + auto r = QCryptographicHash::hash(data, algo); + } +} + +void tst_QCryptographicHash::addData() +{ + QFETCH(const Algorithm, algo); + QFETCH(QByteArray, data); + + SKIP_IF_NOT_SUPPORTED(algo); + + QCryptographicHash hash(algo); + QBENCHMARK { + hash.reset(); + hash.addData(data); + [[maybe_unused]] + auto r = hash.resultView(); + } +} + +void tst_QCryptographicHash::addDataChunked() +{ + QFETCH(const Algorithm, algo); + QFETCH(QByteArray, data); + + SKIP_IF_NOT_SUPPORTED(algo); + + QCryptographicHash hash(algo); + QBENCHMARK { + hash.reset(); + + // add the data in chunks of 64 bytes + for (int i = 0; i < data.size() / 64; ++i) + hash.addData({data.constData() + 64 * i, 64}); + hash.addData({data.constData() + data.size() / 64 * 64, data.size() % 64}); + + [[maybe_unused]] + auto r = hash.resultView(); + } +} + +static QByteArray hmacKey() { + static QByteArray key = [] { + QByteArray result(277, Qt::Uninitialized); + std::iota(result.begin(), result.end(), uchar(0)); // uchar so wraps after UCHAR_MAX + return result; + }(); + return key; +} + +void tst_QCryptographicHash::hmac_hash() +{ + QFETCH(const Algorithm, algo); + QFETCH(const QByteArray, data); + + SKIP_IF_NOT_SUPPORTED(algo); + + const auto key = hmacKey(); + QBENCHMARK { + [[maybe_unused]] + auto r = QMessageAuthenticationCode::hash(data, key, algo); + } +} + +void tst_QCryptographicHash::hmac_addData() +{ + QFETCH(const Algorithm, algo); + QFETCH(const QByteArray, data); + + SKIP_IF_NOT_SUPPORTED(algo); + + const auto key = hmacKey(); + QMessageAuthenticationCode mac(algo, key); + QBENCHMARK { + mac.reset(); + mac.addData(data); + [[maybe_unused]] + auto r = mac.resultView(); + } +} + +void tst_QCryptographicHash::hmac_setKey_data() +{ + QTest::addColumn<Algorithm>("algo"); + for_each_algorithm([] (Algorithm algo, const char *name) { + if (algo == Algorithm::NumAlgorithms) + return; + QTest::addRow("%s", name) << algo; + }); +} + +void tst_QCryptographicHash::hmac_setKey() +{ + QFETCH(const Algorithm, algo); + + SKIP_IF_NOT_SUPPORTED(algo); + + const QByteArrayList keys = [] { + QByteArrayList result; + const auto fullKey = hmacKey(); + result.reserve(fullKey.size()); + for (auto i = fullKey.size(); i > 0; --i) + result.push_back(fullKey.sliced(i)); + return result; + }(); + + QMessageAuthenticationCode mac(algo); + QBENCHMARK { + for (const auto &key : keys) { + mac.setKey(key); + mac.addData("abc", 3); // avoid lazy setKey() + } + } +} + +#undef SKIP_IF_NOT_SUPPORTED + +QTEST_APPLESS_MAIN(tst_QCryptographicHash) + +#include "tst_bench_qcryptographichash.moc" diff --git a/tests/benchmarks/corelib/tools/qdatetime/CMakeLists.txt b/tests/benchmarks/corelib/tools/qdatetime/CMakeLists.txt deleted file mode 100644 index 6875fdd613..0000000000 --- a/tests/benchmarks/corelib/tools/qdatetime/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -add_qt_test(tst_bench_qdatetime SOURCES main.cpp) diff --git a/tests/benchmarks/corelib/tools/qhash/CMakeLists.txt b/tests/benchmarks/corelib/tools/qhash/CMakeLists.txt index 760b1848d7..9002cc0723 100644 --- a/tests/benchmarks/corelib/tools/qhash/CMakeLists.txt +++ b/tests/benchmarks/corelib/tools/qhash/CMakeLists.txt @@ -1,15 +1,18 @@ -# Generated from qhash.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### -## tst_hash Binary: +## tst_bench_qhash Binary: ##################################################################### -qt_add_benchmark(tst_hash +qt_internal_add_benchmark(tst_bench_qhash SOURCES - main.cpp + tst_bench_qhash.cpp outofline.cpp + NO_PCH_SOURCES + tst_bench_qhash.cpp # undef QT_NO_FOREACH INCLUDE_DIRECTORIES . - PUBLIC_LIBRARIES + LIBRARIES Qt::Test ) diff --git a/tests/benchmarks/corelib/tools/qhash/main.h b/tests/benchmarks/corelib/tools/qhash/main.h deleted file mode 100644 index eca4b61d58..0000000000 --- a/tests/benchmarks/corelib/tools/qhash/main.h +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtTest module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QString> - -struct Qt4String : QString -{ - Qt4String() {} - Qt4String(const QString &s) : QString(s) {} -}; - -QT_BEGIN_NAMESPACE -uint qHash(const Qt4String &); -QT_END_NAMESPACE - -struct Qt50String : QString -{ - Qt50String() {} - Qt50String(const QString &s) : QString(s) {} -}; - -QT_BEGIN_NAMESPACE -uint qHash(const Qt50String &, uint seed = 0); -QT_END_NAMESPACE - - -struct JavaString : QString -{ - JavaString() {} - JavaString(const QString &s) : QString(s) {} -}; - -QT_BEGIN_NAMESPACE -uint qHash(const JavaString &); -QT_END_NAMESPACE - diff --git a/tests/benchmarks/corelib/tools/qhash/outofline.cpp b/tests/benchmarks/corelib/tools/qhash/outofline.cpp index 4e449e76b4..5b16c36ffb 100644 --- a/tests/benchmarks/corelib/tools/qhash/outofline.cpp +++ b/tests/benchmarks/corelib/tools/qhash/outofline.cpp @@ -1,38 +1,13 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtTest module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only -#include "main.h" +#include "tst_bench_qhash.h" QT_BEGIN_NAMESPACE -uint qHash(const Qt4String &str) +size_t qHash(const Qt4String &str, size_t /* never used */) { - int n = str.length(); + qsizetype n = str.size(); const QChar *p = str.unicode(); uint h = 0; @@ -44,11 +19,11 @@ uint qHash(const Qt4String &str) return h; } -uint qHash(const Qt50String &key, uint seed) +size_t qHash(const Qt50String &key, size_t seed) { const QChar *p = key.unicode(); - int len = key.size(); - uint h = seed; + qsizetype len = key.size(); + size_t h = seed; for (int i = 0; i < len; ++i) h = 31 * h + p[i].unicode(); return h; @@ -65,10 +40,10 @@ uint qHash(const Qt50String &key, uint seed) // Still, we can avoid writing the multiplication as "(h << 5) - h" // -- the compiler will turn it into a shift and an addition anyway // (for instance, gcc 4.4 does that even at -O0). -uint qHash(const JavaString &str) +size_t qHash(const JavaString &str, size_t /* never used */) { - const unsigned short *p = (unsigned short *)str.constData(); - const int len = str.size(); + const auto *p = reinterpret_cast<const char16_t *>(str.constData()); + const qsizetype len = str.size(); uint h = 0; diff --git a/tests/benchmarks/corelib/tools/qhash/qhash.pro b/tests/benchmarks/corelib/tools/qhash/qhash.pro deleted file mode 100644 index f9a873d096..0000000000 --- a/tests/benchmarks/corelib/tools/qhash/qhash.pro +++ /dev/null @@ -1,6 +0,0 @@ -CONFIG += benchmark -QT = core testlib - -INCLUDEPATH += . -TARGET = tst_hash -SOURCES += main.cpp outofline.cpp diff --git a/tests/benchmarks/corelib/tools/qhash/main.cpp b/tests/benchmarks/corelib/tools/qhash/tst_bench_qhash.cpp index f9b1624fcc..1a62a48437 100644 --- a/tests/benchmarks/corelib/tools/qhash/main.cpp +++ b/tests/benchmarks/corelib/tools/qhash/tst_bench_qhash.cpp @@ -1,33 +1,10 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Intel Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "main.h" +// Copyright (C) 2016 The Qt Company Ltd. +// Copyright (C) 2016 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#undef QT_NO_FOREACH // this file contains unported legacy Q_FOREACH uses + +#include "tst_bench_qhash.h" #include <QFile> #include <QHash> @@ -36,6 +13,8 @@ #include <QUuid> #include <QTest> +static constexpr quint64 RandomSeed32 = 1045982819; +static constexpr quint64 RandomSeed64 = QtPrivate::QHashCombine{}(RandomSeed32, RandomSeed32); class tst_QHash : public QObject { @@ -54,6 +33,8 @@ private slots: void hashing_current_data() { data(); } void hashing_current() { hashing_template<QString>(); } + void hashing_qbytearray_data() { data(); } + void hashing_qbytearray() { hashing_template<QByteArray>(); } void hashing_qt50_data() { data(); } void hashing_qt50() { hashing_template<Qt50String>(); } void hashing_qt4_data() { data(); } @@ -61,15 +42,25 @@ private slots: void hashing_javaString_data() { data(); } void hashing_javaString() { hashing_template<JavaString>(); } + void hashing_nonzero_current_data() { data(); } + void hashing_nonzero_current() { hashing_nonzero_template<QString>(); } + void hashing_nonzero_qbytearray_data() { data(); } + void hashing_nonzero_qbytearray() { hashing_nonzero_template<QByteArray>(); } + void hashing_nonzero_qlatin1string_data() { data(); } + void hashing_nonzero_qlatin1string() { hashing_nonzero_template<OwningLatin1String>(); } + private: void data(); template <typename String> void qhash_template(); - template <typename String> void hashing_template(); + template <typename String, size_t Seed = 0> void hashing_template(); + template <typename String> void hashing_nonzero_template() + { hashing_template<String, size_t(RandomSeed64)>(); } QStringList smallFilePaths; QStringList uuids; QStringList dict; QStringList numbers; + QStringList longstrings; }; ///////////////////// QHash ///////////////////// @@ -78,7 +69,10 @@ private: void tst_QHash::initTestCase() { - // small list of file paths + QHashSeed::setDeterministicGlobalSeed(); + + // small list of strings (that happen to look like file paths produced long + // ago by cd ../.. && find . -print, but that's irrelevant). QFile smallPathsData(QFINDTESTDATA("paths_small_data.txt")); QVERIFY(smallPathsData.open(QIODevice::ReadOnly)); smallFilePaths = QString::fromLatin1(smallPathsData.readAll()).split(QLatin1Char('\n')); @@ -88,15 +82,17 @@ void tst_QHash::initTestCase() // guaranteed to be completely random, generated by http://xkcd.com/221/ QUuid ns = QUuid("{f43d2ef3-2fe9-4563-a6f5-5a0100c2d699}"); uuids.reserve(smallFilePaths.size()); + longstrings.reserve(smallFilePaths.size()); foreach (const QString &path, smallFilePaths) uuids.append(QUuid::createUuidV5(ns, path).toString()); - + for (qsizetype i = 0; i < uuids.size(); ++i) + longstrings.append(uuids.at(i).repeated(8)); // lots of strings with alphabetical characters, vaguely reminiscent of // a dictionary. // - // this programatically generates a series like: + // this programmatically generates a series like: // AAAAAA // AAAAAB // AAAAAC @@ -109,7 +105,7 @@ void tst_QHash::initTestCase() QByteArray id("AAAAAAA"); if (dict.isEmpty()) { - for (int i = id.length() - 1; i > 0;) { + for (int i = id.size() - 1; i > 0;) { dict.append(id); char c = id.at(i); id[i] = ++c; @@ -132,6 +128,7 @@ void tst_QHash::data() QTest::addColumn<QStringList>("items"); QTest::newRow("paths-small") << smallFilePaths; QTest::newRow("uuids-list") << uuids; + QTest::newRow("longstrings-list") << longstrings; QTest::newRow("dictionary") << dict; QTest::newRow("numbers") << numbers; } @@ -152,22 +149,33 @@ template <typename String> void tst_QHash::qhash_template() } } -template <typename String> void tst_QHash::hashing_template() +template <typename String, size_t Seed> void tst_QHash::hashing_template() { // just the hashing function QFETCH(QStringList, items); QList<String> realitems; realitems.reserve(items.size()); - foreach (const QString &s, items) - realitems.append(s); + foreach (const QString &s, items) { + if constexpr (std::is_same_v<QString::value_type, typename String::value_type>) { + realitems.append(s); + } else if constexpr (sizeof(typename String::value_type) == 1) { + realitems.append(String(s.toLatin1())); + } + } QBENCHMARK { - for (int i = 0, n = realitems.size(); i != n; ++i) - (void)qHash(realitems.at(i)); + for (int i = 0, n = realitems.size(); i != n; ++i) { + volatile size_t h = qHash(realitems.at(i), Seed); + (void)h; +#ifdef Q_CC_GNU + // "use" h + asm ("" : "+r" (h)); +#endif + } } } QTEST_MAIN(tst_QHash) -#include "main.moc" +#include "tst_bench_qhash.moc" diff --git a/tests/benchmarks/corelib/tools/qhash/tst_bench_qhash.h b/tests/benchmarks/corelib/tools/qhash/tst_bench_qhash.h new file mode 100644 index 0000000000..501b4a8b7f --- /dev/null +++ b/tests/benchmarks/corelib/tools/qhash/tst_bench_qhash.h @@ -0,0 +1,48 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include <QHashFunctions> +#include <QString> + +struct OwningLatin1String : QByteArray +{ + OwningLatin1String() = default; + OwningLatin1String(const QByteArray &a) : QByteArray(a) {} + OwningLatin1String(QByteArray &&a) : QByteArray(std::move(a)) {} +}; +QT_BEGIN_NAMESPACE +inline size_t qHash(const OwningLatin1String &s, size_t seed = 0) +{ return qHash(QLatin1StringView(s), seed); } +QT_END_NAMESPACE + +struct Qt4String : QString +{ + Qt4String() {} + Qt4String(const QString &s) : QString(s) {} +}; + +QT_BEGIN_NAMESPACE +size_t qHash(const Qt4String &, size_t = 0); +QT_END_NAMESPACE + +struct Qt50String : QString +{ + Qt50String() {} + Qt50String(const QString &s) : QString(s) {} +}; + +QT_BEGIN_NAMESPACE +size_t qHash(const Qt50String &, size_t seed = 0); +QT_END_NAMESPACE + + +struct JavaString : QString +{ + JavaString() {} + JavaString(const QString &s) : QString(s) {} +}; + +QT_BEGIN_NAMESPACE +size_t qHash(const JavaString &, size_t = 0); +QT_END_NAMESPACE + diff --git a/tests/benchmarks/corelib/tools/qlist/CMakeLists.txt b/tests/benchmarks/corelib/tools/qlist/CMakeLists.txt index 40be9e9374..dabfe08122 100644 --- a/tests/benchmarks/corelib/tools/qlist/CMakeLists.txt +++ b/tests/benchmarks/corelib/tools/qlist/CMakeLists.txt @@ -1,12 +1,13 @@ -# Generated from qlist.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## tst_bench_qlist Binary: ##################################################################### -qt_add_benchmark(tst_bench_qlist +qt_internal_add_benchmark(tst_bench_qlist SOURCES - main.cpp - PUBLIC_LIBRARIES + tst_bench_qlist.cpp + LIBRARIES Qt::Test ) diff --git a/tests/benchmarks/corelib/tools/qlist/main.cpp b/tests/benchmarks/corelib/tools/qlist/main.cpp deleted file mode 100644 index e276509220..0000000000 --- a/tests/benchmarks/corelib/tools/qlist/main.cpp +++ /dev/null @@ -1,236 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QList> -#include <QTest> - -static const int N = 1000; - -struct MyBase -{ - MyBase(int i_) - : isCopy(false) - { - ++liveCount; - - i = i_; - } - - MyBase(const MyBase &other) - : isCopy(true) - { - if (isCopy) - ++copyCount; - ++liveCount; - - i = other.i; - } - - MyBase &operator=(const MyBase &other) - { - if (!isCopy) { - isCopy = true; - ++copyCount; - } else { - ++errorCount; - } - - i = other.i; - return *this; - } - - ~MyBase() - { - if (isCopy) { - if (!copyCount) - ++errorCount; - else - --copyCount; - } - if (!liveCount) - ++errorCount; - else - --liveCount; - } - - bool operator==(const MyBase &other) const - { return i == other.i; } - -protected: - ushort i; - bool isCopy; - -public: - static int errorCount; - static int liveCount; - static int copyCount; -}; - -int MyBase::errorCount = 0; -int MyBase::liveCount = 0; -int MyBase::copyCount = 0; - -struct MyPrimitive : public MyBase -{ - MyPrimitive(int i = -1) : MyBase(i) - { ++errorCount; } - MyPrimitive(const MyPrimitive &other) : MyBase(other) - { ++errorCount; } - ~MyPrimitive() - { ++errorCount; } -}; - -struct MyMovable : public MyBase -{ - MyMovable(int i = -1) : MyBase(i) {} -}; - -struct MyComplex : public MyBase -{ - MyComplex(int i = -1) : MyBase(i) {} -}; - -QT_BEGIN_NAMESPACE - -Q_DECLARE_TYPEINFO(MyPrimitive, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(MyMovable, Q_MOVABLE_TYPE); -Q_DECLARE_TYPEINFO(MyComplex, Q_COMPLEX_TYPE); - -QT_END_NAMESPACE - - -class tst_QList: public QObject -{ - Q_OBJECT - -private Q_SLOTS: - void removeAll_primitive_data(); - void removeAll_primitive(); - void removeAll_movable_data(); - void removeAll_movable(); - void removeAll_complex_data(); - void removeAll_complex(); -}; - -template <class T> -void removeAll_test(const QList<int> &i10, ushort valueToRemove, int itemsToRemove) -{ - bool isComplex = QTypeInfo<T>::isComplex; - - MyBase::errorCount = 0; - MyBase::liveCount = 0; - MyBase::copyCount = 0; - { - QList<T> list; - QCOMPARE(MyBase::liveCount, 0); - QCOMPARE(MyBase::copyCount, 0); - - for (int i = 0; i < 10 * N; ++i) { - T t(i10.at(i % 10)); - list.append(t); - } - QCOMPARE(MyBase::liveCount, isComplex ? list.size() : 0); - QCOMPARE(MyBase::copyCount, isComplex ? list.size() : 0); - - T t(valueToRemove); - QCOMPARE(MyBase::liveCount, isComplex ? list.size() + 1 : 1); - QCOMPARE(MyBase::copyCount, isComplex ? list.size() : 0); - - int removedCount; - QList<T> l; - - QBENCHMARK { - l = list; - removedCount = l.removeAll(t); - } - QCOMPARE(removedCount, itemsToRemove * N); - QCOMPARE(l.size() + removedCount, list.size()); - QVERIFY(!l.contains(valueToRemove)); - - QCOMPARE(MyBase::liveCount, isComplex ? l.isDetached() ? list.size() + l.size() + 1 : list.size() + 1 : 1); - QCOMPARE(MyBase::copyCount, isComplex ? l.isDetached() ? list.size() + l.size() : list.size() : 0); - } - if (isComplex) - QCOMPARE(MyBase::errorCount, 0); -} - - -void tst_QList::removeAll_primitive_data() -{ - qRegisterMetaType<QList<int> >(); - - QTest::addColumn<QList<int> >("i10"); - QTest::addColumn<int>("valueToRemove"); - QTest::addColumn<int>("itemsToRemove"); - - QTest::newRow("0%") << (QList<int>() << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0) << 5 << 0; - QTest::newRow("10%") << (QList<int>() << 0 << 0 << 0 << 0 << 5 << 0 << 0 << 0 << 0 << 0) << 5 << 1; - QTest::newRow("90%") << (QList<int>() << 5 << 5 << 5 << 5 << 0 << 5 << 5 << 5 << 5 << 5) << 5 << 9; - QTest::newRow("100%") << (QList<int>() << 5 << 5 << 5 << 5 << 5 << 5 << 5 << 5 << 5 << 5) << 5 << 10; -} - -void tst_QList::removeAll_primitive() -{ - QFETCH(QList<int>, i10); - QFETCH(int, valueToRemove); - QFETCH(int, itemsToRemove); - - removeAll_test<MyPrimitive>(i10, valueToRemove, itemsToRemove); -} - -void tst_QList::removeAll_movable_data() -{ - removeAll_primitive_data(); -} - -void tst_QList::removeAll_movable() -{ - QFETCH(QList<int>, i10); - QFETCH(int, valueToRemove); - QFETCH(int, itemsToRemove); - - removeAll_test<MyMovable>(i10, valueToRemove, itemsToRemove); -} - -void tst_QList::removeAll_complex_data() -{ - removeAll_primitive_data(); -} - -void tst_QList::removeAll_complex() -{ - QFETCH(QList<int>, i10); - QFETCH(int, valueToRemove); - QFETCH(int, itemsToRemove); - - removeAll_test<MyComplex>(i10, valueToRemove, itemsToRemove); -} - -QTEST_APPLESS_MAIN(tst_QList) - -#include "main.moc" diff --git a/tests/benchmarks/corelib/tools/qlist/qlist.pro b/tests/benchmarks/corelib/tools/qlist/qlist.pro deleted file mode 100644 index 98767c3250..0000000000 --- a/tests/benchmarks/corelib/tools/qlist/qlist.pro +++ /dev/null @@ -1,5 +0,0 @@ -CONFIG += benchmark -QT = core testlib - -TARGET = tst_bench_qlist -SOURCES += main.cpp diff --git a/tests/benchmarks/corelib/tools/qlist/tst_bench_qlist.cpp b/tests/benchmarks/corelib/tools/qlist/tst_bench_qlist.cpp new file mode 100644 index 0000000000..24691d1f71 --- /dev/null +++ b/tests/benchmarks/corelib/tools/qlist/tst_bench_qlist.cpp @@ -0,0 +1,410 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include <QList> +#include <QTest> + +#include <utility> + +static const int N = 1000; + +struct MyBase +{ + MyBase(int i_) : i(i_) { } + + MyBase(const MyBase &other) : i(other.i) { } + + MyBase &operator=(const MyBase &other) + { + i = other.i; + return *this; + } + + bool operator==(const MyBase &other) const + { return i == other.i; } + +protected: + int i; +}; + +struct MyPrimitive : public MyBase +{ + MyPrimitive(int i_ = -1) : MyBase(i_) { } + MyPrimitive(const MyPrimitive &other) : MyBase(other) { } + MyPrimitive &operator=(const MyPrimitive &other) + { + MyBase::operator=(other); + return *this; + } +}; + +struct MyMovable : public MyBase +{ + MyMovable(int i_ = -1) : MyBase(i_) {} +}; + +struct MyComplex : public MyBase +{ + MyComplex(int i_ = -1) : MyBase(i_) {} +}; + +QT_BEGIN_NAMESPACE + +Q_DECLARE_TYPEINFO(MyPrimitive, Q_PRIMITIVE_TYPE); +Q_DECLARE_TYPEINFO(MyMovable, Q_RELOCATABLE_TYPE); +Q_DECLARE_TYPEINFO(MyComplex, Q_COMPLEX_TYPE); + +QT_END_NAMESPACE + + +class tst_QList: public QObject +{ + Q_OBJECT + + const int million = 1000000; +private Q_SLOTS: + void removeAll_primitive_data(); + void removeAll_primitive() { removeAll_impl<MyPrimitive>(); } + void removeAll_movable_data() { removeAll_primitive_data(); } + void removeAll_movable() { removeAll_impl<MyMovable>(); } + void removeAll_complex_data() { removeAll_primitive_data(); } + void removeAll_complex() { removeAll_impl<MyComplex>(); } + + // append 1 element: + void appendOne_int_data() const { commonBenchmark_data<int>(); } + void appendOne_primitive_data() const { commonBenchmark_data<MyPrimitive>(); } + void appendOne_movable_data() const { commonBenchmark_data<MyMovable>(); } + void appendOne_complex_data() const { commonBenchmark_data<MyComplex>(); } + void appendOne_QString_data() const { commonBenchmark_data<QString>(); } + + void appendOne_int() const { appendOne_impl<QList, int>(); } // QTBUG-87330 + void appendOne_primitive() const { appendOne_impl<QList, MyPrimitive>(); } + void appendOne_movable() const { appendOne_impl<QList, MyMovable>(); } + void appendOne_complex() const { appendOne_impl<QList, MyComplex>(); } + void appendOne_QString() const { appendOne_impl<QList, QString>(); } + + // prepend 1 element: + void prependOne_int_data() const { commonBenchmark_data<int>(); } + void prependOne_primitive_data() const { commonBenchmark_data<MyPrimitive>(); } + void prependOne_movable_data() const { commonBenchmark_data<MyMovable>(); } + void prependOne_complex_data() const { commonBenchmark_data<MyComplex>(); } + void prependOne_QString_data() const { commonBenchmark_data<QString>(); } + + void prependOne_int() const { prependOne_impl<QList, int>(); } + void prependOne_primitive() const { prependOne_impl<QList, MyPrimitive>(); } + void prependOne_movable() const { prependOne_impl<QList, MyMovable>(); } + void prependOne_complex() const { prependOne_impl<QList, MyComplex>(); } + void prependOne_QString() const { prependOne_impl<QList, QString>(); } + + // insert in middle 1 element (quadratic, slow): + void midInsertOne_int_data() const { commonBenchmark_data<int>(million); } + void midInsertOne_primitive_data() const { commonBenchmark_data<MyPrimitive>(million); } + void midInsertOne_movable_data() const { commonBenchmark_data<MyMovable>(million); } + void midInsertOne_complex_data() const { commonBenchmark_data<MyComplex>(million / 10); } + void midInsertOne_QString_data() const { commonBenchmark_data<QString>(million / 10); } + + void midInsertOne_int() const { midInsertOne_impl<QList, int>(); } + void midInsertOne_primitive() const { midInsertOne_impl<QList, MyPrimitive>(); } + void midInsertOne_movable() const { midInsertOne_impl<QList, MyMovable>(); } + void midInsertOne_complex() const { midInsertOne_impl<QList, MyComplex>(); } + void midInsertOne_QString() const { midInsertOne_impl<QList, QString>(); } + + // append/prepend 1 element - hard times for branch predictor: + void appendPrependOne_int_data() const { commonBenchmark_data<int>(); } + void appendPrependOne_primitive_data() const { commonBenchmark_data<MyPrimitive>(); } + void appendPrependOne_movable_data() const { commonBenchmark_data<MyMovable>(); } + void appendPrependOne_complex_data() const { commonBenchmark_data<MyComplex>(); } + void appendPrependOne_QString_data() const { commonBenchmark_data<QString>(); } + + void appendPrependOne_int() const { appendPrependOne_impl<QList, int>(); } + void appendPrependOne_primitive() const { appendPrependOne_impl<QList, MyPrimitive>(); } + void appendPrependOne_movable() const { appendPrependOne_impl<QList, MyMovable>(); } + void appendPrependOne_complex() const { appendPrependOne_impl<QList, MyComplex>(); } + void appendPrependOne_QString() const { appendPrependOne_impl<QList, QString>(); } + + // prepend half elements, then appen another half: + void prependAppendHalvesOne_int_data() const { commonBenchmark_data<int>(); } + void prependAppendHalvesOne_primitive_data() const { commonBenchmark_data<MyPrimitive>(); } + void prependAppendHalvesOne_movable_data() const { commonBenchmark_data<MyMovable>(); } + void prependAppendHalvesOne_complex_data() const { commonBenchmark_data<MyComplex>(); } + void prependAppendHalvesOne_QString_data() const { commonBenchmark_data<QString>(); } + + void prependAppendHalvesOne_int() const { prependAppendHalvesOne_impl<QList, int>(); } + void prependAppendHalvesOne_primitive() const + { + prependAppendHalvesOne_impl<QList, MyPrimitive>(); + } + void prependAppendHalvesOne_movable() const { prependAppendHalvesOne_impl<QList, MyMovable>(); } + void prependAppendHalvesOne_complex() const { prependAppendHalvesOne_impl<QList, MyComplex>(); } + void prependAppendHalvesOne_QString() const { prependAppendHalvesOne_impl<QList, QString>(); } + + // emplace in middle 1 element (quadratic, slow): + void midEmplaceOne_int_data() const { commonBenchmark_data<int>(million); } + void midEmplaceOne_primitive_data() const { commonBenchmark_data<MyPrimitive>(million); } + void midEmplaceOne_movable_data() const { commonBenchmark_data<MyMovable>(million); } + void midEmplaceOne_complex_data() const { commonBenchmark_data<MyComplex>(million / 10); } + void midEmplaceOne_QString_data() const { commonBenchmark_data<QString>(million / 10); } + + void midEmplaceOne_int() const { midEmplaceOne_impl<QList, int>(); } + void midEmplaceOne_primitive() const { midEmplaceOne_impl<QList, MyPrimitive>(); } + void midEmplaceOne_movable() const { midEmplaceOne_impl<QList, MyMovable>(); } + void midEmplaceOne_complex() const { midEmplaceOne_impl<QList, MyComplex>(); } + void midEmplaceOne_QString() const { midEmplaceOne_impl<QList, QString>(); } + + // remove from beginning in a general way + void removeFirstGeneral_int_data() const { commonBenchmark_data<int>(); } + void removeFirstGeneral_primitive_data() const { commonBenchmark_data<MyPrimitive>(); } + void removeFirstGeneral_movable_data() const { commonBenchmark_data<MyMovable>(); } + void removeFirstGeneral_complex_data() const { commonBenchmark_data<MyComplex>(); } + void removeFirstGeneral_QString_data() const { commonBenchmark_data<QString>(); } + + void removeFirstGeneral_int() const { removeFirstGeneral_impl<QList, int>(); } + void removeFirstGeneral_primitive() const { removeFirstGeneral_impl<QList, MyPrimitive>(); } + void removeFirstGeneral_movable() const { removeFirstGeneral_impl<QList, MyMovable>(); } + void removeFirstGeneral_complex() const { removeFirstGeneral_impl<QList, MyComplex>(); } + void removeFirstGeneral_QString() const { removeFirstGeneral_impl<QList, QString>(); } + + // remove from beginning in a special way (using fast part of QList::removeFirst()) + void removeFirstSpecial_int_data() const { commonBenchmark_data<int>(); } + void removeFirstSpecial_primitive_data() const { commonBenchmark_data<MyPrimitive>(); } + void removeFirstSpecial_movable_data() const { commonBenchmark_data<MyMovable>(); } + void removeFirstSpecial_complex_data() const { commonBenchmark_data<MyComplex>(); } + void removeFirstSpecial_QString_data() const { commonBenchmark_data<QString>(); } + + void removeFirstSpecial_int() const { removeFirstSpecial_impl<QList, int>(); } + void removeFirstSpecial_primitive() const { removeFirstSpecial_impl<QList, MyPrimitive>(); } + void removeFirstSpecial_movable() const { removeFirstSpecial_impl<QList, MyMovable>(); } + void removeFirstSpecial_complex() const { removeFirstSpecial_impl<QList, MyComplex>(); } + void removeFirstSpecial_QString() const { removeFirstSpecial_impl<QList, QString>(); } + +private: + template <class T> + void removeAll_impl() const; + + template<typename> + void commonBenchmark_data(int max = 200000000) const; + + template<template<typename> typename, typename> + void appendOne_impl() const; + + template<template<typename> typename, typename> + void prependOne_impl() const; + + template<template<typename> typename, typename> + void midInsertOne_impl() const; + + template<template<typename> typename, typename> + void appendPrependOne_impl() const; + + template<template<typename> typename, typename> + void prependAppendHalvesOne_impl() const; + + template<template<typename> typename, typename> + void midEmplaceOne_impl() const; + + template<template<typename> typename, typename> + void removeFirstGeneral_impl() const; + + template<template<typename> typename, typename> + void removeFirstSpecial_impl() const; +}; + +template <class T> +void tst_QList::removeAll_impl() const +{ + QFETCH(QList<int>, i10); + QFETCH(int, itemsToRemove); + + constexpr int valueToRemove = 5; + + QList<T> list; + for (int i = 0; i < 10 * N; ++i) { + T t(i10.at(i % 10)); + list.append(t); + } + + T t(valueToRemove); + + qsizetype removedCount = 0; // make compiler happy by setting to 0 + QList<T> l; + + QBENCHMARK { + l = list; + removedCount = l.removeAll(t); + } + QCOMPARE(removedCount, itemsToRemove * N); + QCOMPARE(l.size() + removedCount, list.size()); + QVERIFY(!l.contains(valueToRemove)); +} + +void tst_QList::removeAll_primitive_data() +{ + qRegisterMetaType<QList<int> >(); + + QTest::addColumn<QList<int> >("i10"); + QTest::addColumn<int>("itemsToRemove"); + + QTest::newRow("0%") << QList<int>(10, 0) << 0; + QTest::newRow("10%") << (QList<int>() << 0 << 0 << 0 << 0 << 5 << 0 << 0 << 0 << 0 << 0) << 1; + QTest::newRow("90%") << (QList<int>() << 5 << 5 << 5 << 5 << 0 << 5 << 5 << 5 << 5 << 5) << 9; + QTest::newRow("100%") << QList<int>(10, 5) << 10; +} + +template<typename T> +void tst_QList::commonBenchmark_data(int max) const +{ + QTest::addColumn<int>("elemCount"); + + const auto addRow = [](int count, const char *text) { QTest::newRow(text) << count; }; + + const auto p = [](int i, const char *text) { return std::make_pair(i, text); }; + + // cap at 20m elements to allow 5.15/6.0 coverage to be the same + for (auto pair : { p(100, "100"), p(1000, "1k"), p(10000, "10k"), p(100000, "100k"), + p(1000000, "1m"), p(10000000, "10m"), p(20000000, "20m") }) { + if (pair.first <= max) + addRow(pair.first, pair.second); + } +} + +template<template<typename> typename Container, typename T> +void tst_QList::appendOne_impl() const +{ + QFETCH(int, elemCount); + constexpr auto getValue = []() { return T {}; }; + + QBENCHMARK { + Container<T> container; + auto lvalue = getValue(); + + for (int i = 0; i < elemCount; ++i) { + container.append(lvalue); + } + } +} + +template<template<typename> typename Container, typename T> +void tst_QList::prependOne_impl() const +{ + QFETCH(int, elemCount); + constexpr auto getValue = []() { return T {}; }; + + QBENCHMARK { + Container<T> container; + auto lvalue = getValue(); + + for (int i = 0; i < elemCount; ++i) { + container.prepend(lvalue); + } + } +} + +template<template<typename> typename Container, typename T> +void tst_QList::midInsertOne_impl() const +{ + QFETCH(int, elemCount); + constexpr auto getValue = []() { return T {}; }; + + QBENCHMARK { + Container<T> container; + auto lvalue = getValue(); + + for (int i = 0; i < elemCount; ++i) { + const int remainder = i % 2; + // use insert(i, n, t) as insert(i, t) calls emplace (implementation + // detail) + container.insert(container.size() / 2 + remainder, 1, lvalue); + } + } +} + +template<template<typename> typename Container, typename T> +void tst_QList::appendPrependOne_impl() const +{ + QFETCH(int, elemCount); + constexpr auto getValue = []() { return T {}; }; + + QBENCHMARK { + Container<T> container; + auto lvalue = getValue(); + + for (int i = 0; i < elemCount; ++i) { + if (i % 2 == 0) { + container.append(lvalue); + } else { + container.prepend(lvalue); + } + } + } +} + +template<template<typename> typename Container, typename T> +void tst_QList::prependAppendHalvesOne_impl() const +{ + QFETCH(int, elemCount); + constexpr auto getValue = []() { return T {}; }; + + QBENCHMARK { + Container<T> container; + auto lvalue = getValue(); + + for (int i = 0; i < elemCount / 2; ++i) { + container.prepend(lvalue); + } + + for (int i = elemCount / 2; i < elemCount; ++i) { + container.append(lvalue); + } + } +} + +template<template<typename> typename Container, typename T> +void tst_QList::midEmplaceOne_impl() const +{ + QFETCH(int, elemCount); + constexpr auto getValue = []() { return T {}; }; + + QBENCHMARK { + Container<T> container; + auto lvalue = getValue(); + + for (int i = 0; i < elemCount; ++i) { + const int remainder = i % 2; + container.emplace(container.size() / 2 + remainder, lvalue); + } + } +} + +template<template<typename> typename Container, typename T> +void tst_QList::removeFirstGeneral_impl() const +{ + QFETCH(int, elemCount); + constexpr auto getValue = []() { return T {}; }; + + QBENCHMARK { + Container<T> container(elemCount, getValue()); + + for (int i = 0; i < elemCount - 1; ++i) { + container.remove(0, 1); + } + } +} + +template<template<typename> typename Container, typename T> +void tst_QList::removeFirstSpecial_impl() const +{ + QFETCH(int, elemCount); + constexpr auto getValue = []() { return T {}; }; + + QBENCHMARK { + Container<T> container(elemCount, getValue()); + + for (int i = 0; i < elemCount; ++i) { + container.removeFirst(); + } + } +} + +QTEST_APPLESS_MAIN(tst_QList) + +#include "tst_bench_qlist.moc" diff --git a/tests/benchmarks/corelib/tools/qlocale/CMakeLists.txt b/tests/benchmarks/corelib/tools/qlocale/CMakeLists.txt deleted file mode 100644 index b8a23bc757..0000000000 --- a/tests/benchmarks/corelib/tools/qlocale/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -add_qt_test(tst_bench_qlocale SOURCES main.cpp) diff --git a/tests/benchmarks/corelib/tools/qmap/CMakeLists.txt b/tests/benchmarks/corelib/tools/qmap/CMakeLists.txt index b814b018c0..4dc3dbb258 100644 --- a/tests/benchmarks/corelib/tools/qmap/CMakeLists.txt +++ b/tests/benchmarks/corelib/tools/qmap/CMakeLists.txt @@ -1,14 +1,15 @@ -# Generated from qmap.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## tst_bench_qmap Binary: ##################################################################### -qt_add_benchmark(tst_bench_qmap +qt_internal_add_benchmark(tst_bench_qmap SOURCES - main.cpp + tst_bench_qmap.cpp INCLUDE_DIRECTORIES . - PUBLIC_LIBRARIES + LIBRARIES Qt::Test ) diff --git a/tests/benchmarks/corelib/tools/qmap/qmap.pro b/tests/benchmarks/corelib/tools/qmap/qmap.pro deleted file mode 100644 index 0e06493c79..0000000000 --- a/tests/benchmarks/corelib/tools/qmap/qmap.pro +++ /dev/null @@ -1,6 +0,0 @@ -CONFIG += benchmark -QT = core testlib - -INCLUDEPATH += . -TARGET = tst_bench_qmap -SOURCES += main.cpp diff --git a/tests/benchmarks/corelib/tools/qmap/main.cpp b/tests/benchmarks/corelib/tools/qmap/tst_bench_qmap.cpp index 50cc853df6..db3c4fc7a2 100644 --- a/tests/benchmarks/corelib/tools/qmap/main.cpp +++ b/tests/benchmarks/corelib/tools/qmap/tst_bench_qmap.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QFile> #include <QMap> @@ -61,16 +36,41 @@ private slots: void insertion_string_int2_hint(); void insertMap(); + +private: + QStringList helloEachWorld(int count); }; +QStringList tst_QMap::helloEachWorld(int count) +{ + QStringList result; + result.reserve(count); + result << QStringLiteral("Hello World"); // at index 0, not used + + char16_t name[] = u"Hello World"; + QStringView str(name); + for (int i = 1; i < count; ++i) { + auto p = name + 6; // In the gap between words. + for (const auto ch : QChar::fromUcs4(i)) + p++[0] = ch; + result << str.toString(); + } + return result; +} + +constexpr int huge = 100000; // one hundred thousand; simple integral data tests +// Sum of i with 0 <= i < huge; overflows, but that's OK as long as it's unsigned: +constexpr uint hugeSum = (uint(huge) / 2) * uint(huge - 1); +constexpr int bigish = 5000; // five thousand; tests using XString's expensive < void tst_QMap::insertion_int_int() { QMap<int, int> map; QBENCHMARK { - for (int i = 0; i < 100000; ++i) + for (int i = 0; i < huge; ++i) map.insert(i, i); } + QCOMPARE(map.size(), qsizetype(huge)); } void tst_QMap::insertion_int_intx() @@ -79,36 +79,40 @@ void tst_QMap::insertion_int_intx() // The results in the beginning of the test seems to be a somewhat inaccurate. QMap<int, int> map; QBENCHMARK { - for (int i = 0; i < 100000; ++i) + for (int i = 0; i < huge; ++i) map.insert(i, i); } + QCOMPARE(map.size(), qsizetype(huge)); } void tst_QMap::insertion_int_int_with_hint1() { QMap<int, int> map; QBENCHMARK { - for (int i = 0; i < 100000; ++i) + for (int i = 0; i < huge; ++i) map.insert(map.constEnd(), i, i); } + QCOMPARE(map.size(), qsizetype(huge)); } void tst_QMap::insertion_int_int2() { QMap<int, int> map; QBENCHMARK { - for (int i = 100000; i >= 0; --i) + for (int i = huge; i >= 0; --i) map.insert(i, i); } + QCOMPARE(map.size(), qsizetype(huge) + 1); } void tst_QMap::insertion_int_int_with_hint2() { QMap<int, int> map; QBENCHMARK { - for (int i = 100000; i >= 0; --i) + for (int i = huge; i >= 0; --i) map.insert(map.constBegin(), i, i); } + QCOMPARE(map.size(), qsizetype(huge) + 1); } void tst_QMap::insertion_int_string() @@ -116,93 +120,100 @@ void tst_QMap::insertion_int_string() QMap<int, QString> map; QString str("Hello World"); QBENCHMARK { - for (int i = 0; i < 100000; ++i) + for (int i = 0; i < huge; ++i) map.insert(i, str); } + QCOMPARE(map.size(), qsizetype(huge)); } void tst_QMap::insertion_string_int() { QMap<QString, int> map; - QString str("Hello World"); + const QStringList names = helloEachWorld(huge); + QCOMPARE(names.size(), qsizetype(huge)); QBENCHMARK { - for (int i = 1; i < 100000; ++i) { - str[0] = QChar(i); - map.insert(str, i); - } + for (int i = 1; i < huge; ++i) + map.insert(names.at(i), i); } + QCOMPARE(map.size() + 1, qsizetype(huge)); } - void tst_QMap::lookup_int_int() { QMap<int, int> map; - for (int i = 0; i < 100000; ++i) + for (int i = 0; i < huge; ++i) map.insert(i, i); + QCOMPARE(map.size(), qsizetype(huge)); - int sum = 0; + uint sum = 0, count = 0; QBENCHMARK { - for (int i = 0; i < 100000; ++i) + for (int i = 0; i < huge; ++i) sum += map.value(i); + ++count; } + QCOMPARE(sum, hugeSum * count); } void tst_QMap::lookup_int_string() { QMap<int, QString> map; QString str("Hello World"); - for (int i = 0; i < 100000; ++i) + for (int i = 0; i < huge; ++i) map.insert(i, str); + QCOMPARE(map.size(), qsizetype(huge)); QBENCHMARK { - for (int i = 0; i < 100000; ++i) - str += map.value(i); + for (int i = 0; i < huge; ++i) + str = map.value(i); } } void tst_QMap::lookup_string_int() { QMap<QString, int> map; - QString str("Hello World"); - for (int i = 1; i < 100000; ++i) { - str[0] = QChar(i); - map.insert(str, i); - } + const QStringList names = helloEachWorld(huge); + for (int i = 1; i < huge; ++i) + map.insert(names.at(i), i); + QCOMPARE(map.size() + 1, qsizetype(huge)); - int sum = 0; + uint sum = 0, count = 0; QBENCHMARK { - for (int i = 1; i < 100000; ++i) { - str[0] = QChar(i); - sum += map.value(str); - } + for (int i = 1; i < huge; ++i) + sum += map.value(names.at(i)); + ++count; } + QCOMPARE(sum, hugeSum * count); } // iteration speed doesn't depend on the type of the map. void tst_QMap::iteration() { QMap<int, int> map; - for (int i = 0; i < 100000; ++i) + for (int i = 0; i < huge; ++i) map.insert(i, i); + QCOMPARE(map.size(), qsizetype(huge)); - int j = 0; + uint sum = 0, count = 0; QBENCHMARK { for (int i = 0; i < 100; ++i) { QMap<int, int>::const_iterator it = map.constBegin(); QMap<int, int>::const_iterator end = map.constEnd(); while (it != end) { - j += *it; + sum += *it; ++it; } } + ++count; } + QCOMPARE(sum, hugeSum * 100u * count); } void tst_QMap::toStdMap() { QMap<int, int> map; - for (int i = 0; i < 100000; ++i) + for (int i = 0; i < huge; ++i) map.insert(i, i); + QCOMPARE(map.size(), qsizetype(huge)); QBENCHMARK { std::map<int, int> n = map.toStdMap(); @@ -213,11 +224,12 @@ void tst_QMap::toStdMap() void tst_QMap::iterator_begin() { QMap<int, int> map; - for (int i = 0; i < 100000; ++i) + for (int i = 0; i < huge; ++i) map.insert(i, i); + QCOMPARE(map.size(), qsizetype(huge)); QBENCHMARK { - for (int i = 0; i < 100000; ++i) { + for (int i = 0; i < huge; ++i) { QMap<int, int>::const_iterator it = map.constBegin(); QMap<int, int>::const_iterator end = map.constEnd(); if (it == end) // same as if (false) @@ -229,8 +241,9 @@ void tst_QMap::iterator_begin() void tst_QMap::ctorStdMap() { std::map<int, int> map; - for (int i = 0; i < 100000; ++i) + for (int i = 0; i < huge; ++i) map.insert(std::pair<int, int>(i, i)); + QCOMPARE(map.size(), size_t(huge)); QBENCHMARK { QMap<int, int> qmap(map); @@ -251,33 +264,35 @@ void tst_QMap::insertion_string_int2() { QMap<XString, int> map; QBENCHMARK { - for (int i = 1; i < 5000; ++i) { + for (int i = 1; i < bigish; ++i) { XString str; str.setNum(i); map.insert(str, i); } } + QCOMPARE(map.size() + 1, qsizetype(bigish)); } void tst_QMap::insertion_string_int2_hint() { QMap<XString, int> map; QBENCHMARK { - for (int i = 1; i < 5000; ++i) { + for (int i = 1; i < bigish; ++i) { XString str; str.setNum(i); map.insert(map.end(), str, i); } } + QCOMPARE(map.size() + 1, qsizetype(bigish)); } void tst_QMap::insertMap() { QMap<int, int> map; - for (int i = 0; i < 100000; ++i) + for (int i = 0; i < huge; ++i) map.insert(i * 4, 0); QMap<int, int> map2; - for (int i = 0; i < 50000; ++i) + for (int i = 0; i < huge / 2; ++i) map2.insert(i * 7, 0); QBENCHMARK_ONCE { map.insert(map2); @@ -286,4 +301,4 @@ void tst_QMap::insertMap() QTEST_MAIN(tst_QMap) -#include "main.moc" +#include "tst_bench_qmap.moc" diff --git a/tests/benchmarks/corelib/tools/qrect/CMakeLists.txt b/tests/benchmarks/corelib/tools/qrect/CMakeLists.txt index fd9ea5a6f2..e28ca82c74 100644 --- a/tests/benchmarks/corelib/tools/qrect/CMakeLists.txt +++ b/tests/benchmarks/corelib/tools/qrect/CMakeLists.txt @@ -1,15 +1,13 @@ -# Generated from qrect.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## tst_bench_qrect Binary: ##################################################################### -qt_add_benchmark(tst_bench_qrect +qt_internal_add_benchmark(tst_bench_qrect SOURCES - main.cpp - PUBLIC_LIBRARIES + tst_bench_qrect.cpp + LIBRARIES Qt::Test ) - -#### Keys ignored in scope 1:.:.:qrect.pro:<TRUE>: -# TEMPLATE = "app" diff --git a/tests/benchmarks/corelib/tools/qrect/qrect.pro b/tests/benchmarks/corelib/tools/qrect/qrect.pro deleted file mode 100644 index 211cdc5bcc..0000000000 --- a/tests/benchmarks/corelib/tools/qrect/qrect.pro +++ /dev/null @@ -1,6 +0,0 @@ -TEMPLATE = app -QT = core testlib -CONFIG += benchmark - -TARGET = tst_bench_qrect -SOURCES += main.cpp diff --git a/tests/benchmarks/corelib/tools/qrect/main.cpp b/tests/benchmarks/corelib/tools/qrect/tst_bench_qrect.cpp index 485e0290f8..0ba9e15963 100644 --- a/tests/benchmarks/corelib/tools/qrect/main.cpp +++ b/tests/benchmarks/corelib/tools/qrect/tst_bench_qrect.cpp @@ -1,36 +1,13 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only // This file contains benchmarks for QRect/QRectF functions. +#undef QT_NO_FOREACH // this file contains unported legacy Q_FOREACH uses + #include <QDebug> #include <qtest.h> -class tst_qrect : public QObject +class tst_QRect : public QObject { Q_OBJECT private slots: @@ -159,12 +136,12 @@ static void addRectPointData(bool includeProperArg = false) } } -void tst_qrect::contains_point_data() +void tst_QRect::contains_point_data() { addRectPointData(true); } -void tst_qrect::contains_point() +void tst_QRect::contains_point() { QFETCH(QRectF, rf); QFETCH(QPointF, pf); @@ -176,12 +153,12 @@ void tst_qrect::contains_point() } } -void tst_qrect::contains_rect_data() +void tst_QRect::contains_rect_data() { addRectRectData(true); } -void tst_qrect::contains_rect() +void tst_QRect::contains_rect() { QFETCH(QRectF, rf1); QFETCH(QRectF, rf2); @@ -193,12 +170,12 @@ void tst_qrect::contains_rect() } } -void tst_qrect::intersects_data() +void tst_QRect::intersects_data() { addRectRectData(); } -void tst_qrect::intersects() +void tst_QRect::intersects() { QFETCH(QRectF, rf1); QFETCH(QRectF, rf2); @@ -209,44 +186,44 @@ void tst_qrect::intersects() } } -void tst_qrect::intersected_data() +void tst_QRect::intersected_data() { addRectRectData(); } -void tst_qrect::intersected() +void tst_QRect::intersected() { QFETCH(QRectF, rf1); QFETCH(QRectF, rf2); QRect r1(rf1.toRect()); QRect r2(rf2.toRect()); QBENCHMARK { - r1.intersected(r2); + Q_UNUSED(r1.intersected(r2)) } } -void tst_qrect::united_data() +void tst_QRect::united_data() { addRectRectData(); } -void tst_qrect::united() +void tst_QRect::united() { QFETCH(QRectF, rf1); QFETCH(QRectF, rf2); QRect r1(rf1.toRect()); QRect r2(rf2.toRect()); QBENCHMARK { - r1.united(r2); + Q_UNUSED(r1.united(r2)) } } -void tst_qrect::contains_point_f_data() +void tst_QRect::contains_point_f_data() { addRectPointData(); } -void tst_qrect::contains_point_f() +void tst_QRect::contains_point_f() { QFETCH(QRectF, rf); QFETCH(QPointF, pf); @@ -255,12 +232,12 @@ void tst_qrect::contains_point_f() } } -void tst_qrect::contains_rect_f_data() +void tst_QRect::contains_rect_f_data() { addRectRectData(); } -void tst_qrect::contains_rect_f() +void tst_QRect::contains_rect_f() { QFETCH(QRectF, rf1); QFETCH(QRectF, rf2); @@ -269,12 +246,12 @@ void tst_qrect::contains_rect_f() } } -void tst_qrect::intersects_f_data() +void tst_QRect::intersects_f_data() { addRectRectData(); } -void tst_qrect::intersects_f() +void tst_QRect::intersects_f() { QFETCH(QRectF, rf1); QFETCH(QRectF, rf2); @@ -283,34 +260,34 @@ void tst_qrect::intersects_f() } } -void tst_qrect::intersected_f_data() +void tst_QRect::intersected_f_data() { addRectRectData(); } -void tst_qrect::intersected_f() +void tst_QRect::intersected_f() { QFETCH(QRectF, rf1); QFETCH(QRectF, rf2); QBENCHMARK { - rf1.intersected(rf2); + Q_UNUSED(rf1.intersected(rf2)) } } -void tst_qrect::united_f_data() +void tst_QRect::united_f_data() { addRectRectData(); } -void tst_qrect::united_f() +void tst_QRect::united_f() { QFETCH(QRectF, rf1); QFETCH(QRectF, rf2); QBENCHMARK { - rf1.united(rf2); + Q_UNUSED(rf1.united(rf2)) } } -QTEST_MAIN(tst_qrect) +QTEST_MAIN(tst_QRect) -#include "main.moc" +#include "tst_bench_qrect.moc" diff --git a/tests/benchmarks/corelib/tools/qringbuffer/CMakeLists.txt b/tests/benchmarks/corelib/tools/qringbuffer/CMakeLists.txt index fd10411ff3..322fbbb83c 100644 --- a/tests/benchmarks/corelib/tools/qringbuffer/CMakeLists.txt +++ b/tests/benchmarks/corelib/tools/qringbuffer/CMakeLists.txt @@ -1,16 +1,14 @@ -# Generated from qringbuffer.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## tst_bench_qringbuffer Binary: ##################################################################### -qt_add_benchmark(tst_bench_qringbuffer +qt_internal_add_benchmark(tst_bench_qringbuffer SOURCES - main.cpp - PUBLIC_LIBRARIES + tst_bench_qringbuffer.cpp + LIBRARIES Qt::CorePrivate Qt::Test ) - -#### Keys ignored in scope 1:.:.:qringbuffer.pro:<TRUE>: -# TEMPLATE = "app" diff --git a/tests/benchmarks/corelib/tools/qringbuffer/main.cpp b/tests/benchmarks/corelib/tools/qringbuffer/main.cpp deleted file mode 100644 index fad30a4e34..0000000000 --- a/tests/benchmarks/corelib/tools/qringbuffer/main.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <private/qringbuffer_p.h> -#include <QByteArray> - -#include <qtest.h> - -class tst_qringbuffer : public QObject -{ - Q_OBJECT -private slots: - void reserveAndRead(); - void free(); -}; - -void tst_qringbuffer::reserveAndRead() -{ - QRingBuffer ringBuffer; - QBENCHMARK { - for (qint64 i = 1; i < 256; ++i) - ringBuffer.reserve(i); - - for (qint64 i = 1; i < 256; ++i) - ringBuffer.read(0, i); - } -} - -void tst_qringbuffer::free() -{ - QRingBuffer ringBuffer; - QBENCHMARK { - ringBuffer.reserve(4096); - ringBuffer.reserve(2048); - ringBuffer.append(QByteArray("01234", 5)); - - ringBuffer.free(1); - ringBuffer.free(4096); - ringBuffer.free(48); - ringBuffer.free(2000); - } -} - -QTEST_MAIN(tst_qringbuffer) - -#include "main.moc" diff --git a/tests/benchmarks/corelib/tools/qringbuffer/qringbuffer.pro b/tests/benchmarks/corelib/tools/qringbuffer/qringbuffer.pro deleted file mode 100644 index 69750865b5..0000000000 --- a/tests/benchmarks/corelib/tools/qringbuffer/qringbuffer.pro +++ /dev/null @@ -1,6 +0,0 @@ -TEMPLATE = app -CONFIG += benchmark -QT = core-private testlib - -TARGET = tst_bench_qringbuffer -SOURCES += main.cpp diff --git a/tests/benchmarks/corelib/tools/qringbuffer/tst_bench_qringbuffer.cpp b/tests/benchmarks/corelib/tools/qringbuffer/tst_bench_qringbuffer.cpp new file mode 100644 index 0000000000..f352cd56a9 --- /dev/null +++ b/tests/benchmarks/corelib/tools/qringbuffer/tst_bench_qringbuffer.cpp @@ -0,0 +1,46 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include <private/qringbuffer_p.h> +#include <QByteArray> + +#include <qtest.h> + +class tst_QRingBuffer : public QObject +{ + Q_OBJECT +private slots: + void reserveAndRead(); + void free(); +}; + +void tst_QRingBuffer::reserveAndRead() +{ + QRingBuffer ringBuffer; + QBENCHMARK { + for (qint64 i = 1; i < 256; ++i) + ringBuffer.reserve(i); + + for (qint64 i = 1; i < 256; ++i) + ringBuffer.read(0, i); + } +} + +void tst_QRingBuffer::free() +{ + QRingBuffer ringBuffer; + QBENCHMARK { + ringBuffer.reserve(4096); + ringBuffer.reserve(2048); + ringBuffer.append(QByteArray("01234", 5)); + + ringBuffer.free(1); + ringBuffer.free(4096); + ringBuffer.free(48); + ringBuffer.free(2000); + } +} + +QTEST_MAIN(tst_QRingBuffer) + +#include "tst_bench_qringbuffer.moc" diff --git a/tests/benchmarks/corelib/tools/qset/CMakeLists.txt b/tests/benchmarks/corelib/tools/qset/CMakeLists.txt index 9627338414..7bbed20106 100644 --- a/tests/benchmarks/corelib/tools/qset/CMakeLists.txt +++ b/tests/benchmarks/corelib/tools/qset/CMakeLists.txt @@ -1,12 +1,13 @@ -# Generated from qset.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### -## tst_qset Binary: +## tst_bench_qset Binary: ##################################################################### -qt_add_benchmark(tst_qset +qt_internal_add_benchmark(tst_bench_qset SOURCES - main.cpp - PUBLIC_LIBRARIES + tst_bench_qset.cpp + LIBRARIES Qt::Test ) diff --git a/tests/benchmarks/corelib/tools/qset/qset.pro b/tests/benchmarks/corelib/tools/qset/qset.pro deleted file mode 100644 index e448683e94..0000000000 --- a/tests/benchmarks/corelib/tools/qset/qset.pro +++ /dev/null @@ -1,5 +0,0 @@ -CONFIG += benchmark -QT = core testlib - -TARGET = tst_qset -SOURCES += main.cpp diff --git a/tests/benchmarks/corelib/tools/qset/main.cpp b/tests/benchmarks/corelib/tools/qset/tst_bench_qset.cpp index f6c40ec160..5bbec05aab 100644 --- a/tests/benchmarks/corelib/tools/qset/main.cpp +++ b/tests/benchmarks/corelib/tools/qset/tst_bench_qset.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QSet> #include <QTest> @@ -34,12 +9,22 @@ class tst_QSet : public QObject Q_OBJECT private slots: + void initTestCase(); void intersect_int_data(); void intersect_int(); void intersect_complexType_data(); void intersect_complexType(); + void unite_int_data(); + void unite_int(); + void contains_then_insert_int_data(); + void contains_then_insert_int(); }; +void tst_QSet::initTestCase() +{ + QHashSeed::setDeterministicGlobalSeed(); +} + void tst_QSet::intersect_int_data() { QTest::addColumn<int>("lhsSize"); @@ -123,6 +108,70 @@ void tst_QSet::intersect_complexType() } } +void tst_QSet::unite_int_data() +{ + QTest::addColumn<int>("lhsSize"); + QTest::addColumn<int>("rhsSize"); + QTest::addColumn<int>("overlap"); + + QTest::newRow("1000000.unite(1000) - 0 overlap") << 1000000 << 1000 << 0; + QTest::newRow("1000000.unite(1000) - 100 overlap") << 1000000 << 1000 << 100; + QTest::newRow("1000000.unite(1000) - 1000 overlap") << 1000000 << 1000 << 1000; + QTest::newRow("1000.unite(1000000) - 0 overlap") << 1000 << 1000000 << 0; + QTest::newRow("1000.unite(1000000) - 100 overlap") << 1000 << 1000000 << 100; + QTest::newRow("1000.unite(1000000) - 1000 overlap") << 1000 << 1000000 << 1000; +} + +auto build_sets(int lhsSize, int rhsSize, int overlap) +{ + QSet<int> lhs; + for (int i = 0; i < lhsSize; ++i) + lhs.insert(i); + + QSet<int> rhs; + for (int i = lhsSize - overlap; i < rhsSize + lhsSize - overlap; ++i) + rhs.insert(i); + + return std::make_pair(lhs, rhs); +} + +void tst_QSet::unite_int() +{ + QFETCH(int, lhsSize); + QFETCH(int, rhsSize); + QFETCH(int, overlap); + + auto [lhs, rhs] = build_sets(lhsSize, rhsSize, overlap); + + QBENCHMARK { + QSet united = QSet(lhs).unite(rhs); + QCOMPARE(united.size(), lhsSize + rhsSize - overlap); + } +} + +void tst_QSet::contains_then_insert_int_data() +{ + unite_int_data(); +} + +void tst_QSet::contains_then_insert_int() +{ + QFETCH(int, lhsSize); + QFETCH(int, rhsSize); + QFETCH(int, overlap); + + auto [lhs, rhs] = build_sets(lhsSize, rhsSize, overlap); + + QBENCHMARK { + QSet copy(lhs); + for (auto i : rhs) { + if (!copy.contains(i)) + copy.insert(i); + } + QCOMPARE(copy.size(), lhsSize + rhsSize - overlap); + } +} + QTEST_MAIN(tst_QSet) -#include "main.moc" +#include "tst_bench_qset.moc" diff --git a/tests/benchmarks/corelib/tools/qsharedpointer/CMakeLists.txt b/tests/benchmarks/corelib/tools/qsharedpointer/CMakeLists.txt new file mode 100644 index 0000000000..6adf1f2e4e --- /dev/null +++ b/tests/benchmarks/corelib/tools/qsharedpointer/CMakeLists.txt @@ -0,0 +1,12 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +qt_internal_add_benchmark(tst_bench_shared_ptr + SOURCES + tst_bench_shared_ptr.cpp + INCLUDE_DIRECTORIES + . + LIBRARIES + Qt::Core + Qt::Test +) diff --git a/tests/benchmarks/corelib/tools/qsharedpointer/tst_bench_shared_ptr.cpp b/tests/benchmarks/corelib/tools/qsharedpointer/tst_bench_shared_ptr.cpp new file mode 100644 index 0000000000..6197863601 --- /dev/null +++ b/tests/benchmarks/corelib/tools/qsharedpointer/tst_bench_shared_ptr.cpp @@ -0,0 +1,111 @@ +// Copyright (C) 2021 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com> +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include <QObject> +#include <QScopeGuard> +#include <QSharedPointer> +#include <QTest> + +#include <atomic> +#include <memory> +#include <thread> +#include <vector> + +#if __has_include(<boost/shared_ptr.hpp>) +# include <boost/shared_ptr.hpp> +# include <boost/make_shared.hpp> + +# ifdef BOOST_NO_EXCEPTIONS +// https://stackoverflow.com/a/9530546/134841 +// https://www.boost.org/doc/libs/1_79_0/libs/throw_exception/doc/html/throw_exception.html#throw_exception +BOOST_NORETURN void boost::throw_exception(const std::exception &) { std::terminate(); } +# if BOOST_VERSION >= 107300 +// https://www.boost.org/doc/libs/1_79_0/libs/throw_exception/doc/html/throw_exception.html#changes_in_1_73_0 +BOOST_NORETURN void boost::throw_exception(const std::exception &, const boost::source_location &) +{ std::terminate(); } +# endif // Boost v1.73 +# endif // BOOST_NO_EXCEPTIONS + +# define ONLY_IF_BOOST(x) x +#else +# define ONLY_IF_BOOST(x) QSKIP("This benchmark requires Boost.SharedPtr.") +#endif + +class tst_QSharedPointer : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void refAndDeref_null_QSP_int() { refAndDeref<QSharedPointer<int>>(); } + void refAndDeref_null_SSP_int() { refAndDeref<std::shared_ptr<int>>(); } + void refAndDeref_null_BSP_int() { ONLY_IF_BOOST(refAndDeref<boost::shared_ptr<int>>()); } + + void refAndDeref_null_QSP_QString() { refAndDeref<QSharedPointer<QString>>(); } + void refAndDeref_null_SSP_QString() { refAndDeref<std::shared_ptr<QString>>(); } + void refAndDeref_null_BSP_QString() { ONLY_IF_BOOST(refAndDeref<boost::shared_ptr<QString>>()); } + + void refAndDeref_nonnull_QSP_int() { refAndDeref(QSharedPointer<int>::create(42)); } + void refAndDeref_nonnull_SSP_int() { refAndDeref(std::make_shared<int>(42)); } + void refAndDeref_nonnull_BSP_int() { ONLY_IF_BOOST(refAndDeref(boost::make_shared<int>(42))); } + + void refAndDeref_nonnull_QSP_QString() { refAndDeref(QSharedPointer<QString>::create(QStringLiteral("Hello"))); } + void refAndDeref_nonnull_SSP_QString() { refAndDeref(std::make_shared<QString>(QStringLiteral("Hello"))); } + void refAndDeref_nonnull_BSP_QString() { ONLY_IF_BOOST(refAndDeref(boost::make_shared<QString>(QStringLiteral("Hello")))); } + +private: + template <typename SP> + void refAndDeref(SP sp = {}) + { + QBENCHMARK { + [[maybe_unused]] auto copy = sp; + } + } + +private Q_SLOTS: + void threadedRefAndDeref_null_QSP_int() { threadedRefAndDeref<QSharedPointer<int>>(); } + void threadedRefAndDeref_null_SSP_int() { threadedRefAndDeref<std::shared_ptr<int>>(); } + void threadedRefAndDeref_null_BSP_int() { ONLY_IF_BOOST(threadedRefAndDeref<boost::shared_ptr<int>>()); } + + void threadedRefAndDeref_null_QSP_QString() { threadedRefAndDeref<QSharedPointer<QString>>(); } + void threadedRefAndDeref_null_SSP_QString() { threadedRefAndDeref<std::shared_ptr<QString>>(); } + void threadedRefAndDeref_null_BSP_QString() { ONLY_IF_BOOST(threadedRefAndDeref<boost::shared_ptr<QString>>()); } + + void threadedRefAndDeref_nonnull_QSP_int() { threadedRefAndDeref(QSharedPointer<int>::create(42)); } + void threadedRefAndDeref_nonnull_SSP_int() { threadedRefAndDeref(std::make_shared<int>(42)); } + void threadedRefAndDeref_nonnull_BSP_int() { ONLY_IF_BOOST(threadedRefAndDeref(boost::make_shared<int>(42))); } + + void threadedRefAndDeref_nonnull_QSP_QString() { threadedRefAndDeref(QSharedPointer<QString>::create(QStringLiteral("Hello"))); } + void threadedRefAndDeref_nonnull_SSP_QString() { threadedRefAndDeref(std::make_shared<QString>(QStringLiteral("Hello"))); } + void threadedRefAndDeref_nonnull_BSP_QString() { ONLY_IF_BOOST(threadedRefAndDeref(boost::make_shared<QString>(QStringLiteral("Hello")))); } + +private: + template <typename SP> + void threadedRefAndDeref(SP sp = {}) + { + std::atomic<bool> cancel = false; + std::vector<std::thread> threads; + const auto numCores = std::max(2U, std::thread::hardware_concurrency()); + for (uint i = 0; i < numCores - 1; ++i) { + threads.emplace_back([sp, &cancel] { + while (!cancel.load(std::memory_order_relaxed)) { + for (int i = 0; i < 100; ++i) + [[maybe_unused]] auto copy = sp; + } + }); + } + const auto join = qScopeGuard([&] { + cancel.store(true, std::memory_order_relaxed); + for (auto &t : threads) + t.join(); + }); + + QBENCHMARK { + [[maybe_unused]] auto copy = sp; + } + } +}; + +QTEST_MAIN(tst_QSharedPointer) + +#include "tst_bench_shared_ptr.moc" diff --git a/tests/benchmarks/corelib/tools/qstack/CMakeLists.txt b/tests/benchmarks/corelib/tools/qstack/CMakeLists.txt index 2389dd51ce..e5ae510521 100644 --- a/tests/benchmarks/corelib/tools/qstack/CMakeLists.txt +++ b/tests/benchmarks/corelib/tools/qstack/CMakeLists.txt @@ -1,13 +1,14 @@ -# Generated from qstack.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### -## tst_bench_stack Binary: +## tst_bench_qstack Binary: ##################################################################### -qt_add_benchmark(tst_bench_stack +qt_internal_add_benchmark(tst_bench_qstack SOURCES - main.cpp - PUBLIC_LIBRARIES + tst_bench_qstack.cpp + LIBRARIES Qt::CorePrivate Qt::Test ) diff --git a/tests/benchmarks/corelib/tools/qstack/main.cpp b/tests/benchmarks/corelib/tools/qstack/main.cpp deleted file mode 100644 index c9466ef2e1..0000000000 --- a/tests/benchmarks/corelib/tools/qstack/main.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 Robin Burchell <robin.burchell@viroteck.net> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QStack> -#include <QDebug> -#include <QtTest> - -#include <vector> - -class tst_QStack: public QObject -{ - Q_OBJECT - -private slots: - void qstack_push(); - void qstack_pop(); - void qstack_pushpopone(); -}; - -const int N = 1000000; - -void tst_QStack::qstack_push() -{ - QStack<int> v; - QBENCHMARK { - for (int i = 0; i != N; ++i) - v.push(i); - v = QStack<int>(); - } -} - -void tst_QStack::qstack_pop() -{ - QStack<int> v; - for (int i = 0; i != N; ++i) - v.push(i); - - QBENCHMARK { - QStack<int> v2 = v; - for (int i = 0; i != N; ++i) { - v2.pop(); - } - } -} - -void tst_QStack::qstack_pushpopone() -{ - QBENCHMARK { - QStack<int> v; - for (int i = 0; i != N; ++i) { - v.push(0); - v.pop(); - } - } -} - -QTEST_MAIN(tst_QStack) - -#include "main.moc" diff --git a/tests/benchmarks/corelib/tools/qstack/qstack.pro b/tests/benchmarks/corelib/tools/qstack/qstack.pro deleted file mode 100644 index 17b7ebd486..0000000000 --- a/tests/benchmarks/corelib/tools/qstack/qstack.pro +++ /dev/null @@ -1,5 +0,0 @@ -CONFIG += benchmark -QT = core testlib core-private - -TARGET = tst_bench_stack -SOURCES += main.cpp diff --git a/tests/benchmarks/corelib/tools/qstack/tst_bench_qstack.cpp b/tests/benchmarks/corelib/tools/qstack/tst_bench_qstack.cpp new file mode 100644 index 0000000000..e0c8cda18c --- /dev/null +++ b/tests/benchmarks/corelib/tools/qstack/tst_bench_qstack.cpp @@ -0,0 +1,59 @@ +// Copyright (C) 2015 Robin Burchell <robin.burchell@viroteck.net> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include <QStack> +#include <QDebug> +#include <QTest> + +#include <vector> + +class tst_QStack: public QObject +{ + Q_OBJECT + +private slots: + void qstack_push(); + void qstack_pop(); + void qstack_pushpopone(); +}; + +const int N = 1000000; + +void tst_QStack::qstack_push() +{ + QStack<int> v; + QBENCHMARK { + for (int i = 0; i != N; ++i) + v.push(i); + v = QStack<int>(); + } +} + +void tst_QStack::qstack_pop() +{ + QStack<int> v; + for (int i = 0; i != N; ++i) + v.push(i); + + QBENCHMARK { + QStack<int> v2 = v; + for (int i = 0; i != N; ++i) { + v2.pop(); + } + } +} + +void tst_QStack::qstack_pushpopone() +{ + QBENCHMARK { + QStack<int> v; + for (int i = 0; i != N; ++i) { + v.push(0); + v.pop(); + } + } +} + +QTEST_MAIN(tst_QStack) + +#include "tst_bench_qstack.moc" diff --git a/tests/benchmarks/corelib/tools/qstring/CMakeLists.txt b/tests/benchmarks/corelib/tools/qstring/CMakeLists.txt deleted file mode 100644 index 1dd6678e8e..0000000000 --- a/tests/benchmarks/corelib/tools/qstring/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -add_qt_test(tst_bench_qstring SOURCES main.cpp) diff --git a/tests/benchmarks/corelib/tools/qtimezone/CMakeLists.txt b/tests/benchmarks/corelib/tools/qtimezone/CMakeLists.txt deleted file mode 100644 index 3947ae1c5e..0000000000 --- a/tests/benchmarks/corelib/tools/qtimezone/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -add_qt_test(tst_bench_qtimezone SOURCES main.cpp) diff --git a/tests/benchmarks/corelib/tools/qvector/CMakeLists.txt b/tests/benchmarks/corelib/tools/qvector/CMakeLists.txt index ae40297604..df2fc8ec6a 100644 --- a/tests/benchmarks/corelib/tools/qvector/CMakeLists.txt +++ b/tests/benchmarks/corelib/tools/qvector/CMakeLists.txt @@ -1,16 +1,17 @@ -# Generated from qvector.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### -## tst_bench_vector Binary: +## tst_bench_qvector Binary: ##################################################################### -qt_add_benchmark(tst_bench_vector +qt_internal_add_benchmark(tst_bench_qvector SOURCES - main.cpp + tst_bench_qvector.cpp outofline.cpp INCLUDE_DIRECTORIES . - PUBLIC_LIBRARIES + LIBRARIES Qt::CorePrivate Qt::Test ) diff --git a/tests/benchmarks/corelib/tools/qvector/main.cpp b/tests/benchmarks/corelib/tools/qvector/main.cpp deleted file mode 100644 index 0bd0dacb3a..0000000000 --- a/tests/benchmarks/corelib/tools/qvector/main.cpp +++ /dev/null @@ -1,414 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QVector> -#include <QDebug> -#include <QtTest> - -#include "qrawvector.h" - -#include <vector> - -/* - -Code generated by g++ 4.3.3. The lines marked with '!' are the ones that get -executed inside the loop. Using the external 's' causes some load making the -loop resembling a 'simple inner loop' in 'real' applications. - - -qvector_mutable_read_access: - -.L166: -! movl -16(%ebp), %edx -! movl (%edx), %eax -! subl $1, %eax -! je .L165 - movl 4(%edx), %eax - movl %eax, 8(%esp) - movl 8(%edx), %eax - movl %esi, (%esp) - movl %eax, 4(%esp) - call _ZN4myns7QVectorIdE7reallocEii -.L165: -! movl -16(%ebp), %eax -! fldl s -! faddl 16(%eax,%ebx,8) -! addl $1, %ebx -! cmpl $10000, %ebx -! fstpl s -! jne .L166 - - -qvector_const_read_access: - - movl -16(%ebp), %edx - xorl %eax, %eax -.L183: -! fldl s -! faddl 16(%edx,%eax,8) -! addl $1, %eax -! cmpl $10000, %eax -! fstpl s -! jne .L183 - - -stdvector_const_read_access and stdvector_mutable_read_access and -qrawvector_const_read_access and qrawvector_mutable_read_access: - - xorl %eax, %eax -.L64: -! fldl s -! faddl (%ebx,%eax,8) -! addl $1, %eax -! cmpl $10000, %eax -! fstpl s -! jne .L64 - - - -Behaviour varies with small modifications, but total is more or -less stable: - -qrawvector_mutable_read_access, using size() instead of N: - -.L145: -! faddl (%edx,%eax,8) -! addl $1, %eax -! cmpl %ecx, %eax -! fstl s -! jne .L145 -! fstp %st(0) - - -qrawvector_mutable_read_access, counting backward: - -.L145: -! faddl (%edx,%eax,8) -! subl $1, %eax -! cmpl $-1, %eax -! fstl s -! jne .L145 - - -qrawvector_mutable_read_access, counting backward, using size(): - -.L146: -! faddl (%edx) -! addl $1, %eax -! subl $8, %edx -! cmpl %ecx, %eax -! fstl s -! jne .L146 - - - -*/ - - -/* - -//////////////////////////////////////////////////////////////////// - -time ./tst_vector qvector_const_read_access -real 0m12.912s -user 0m12.401s -sys 0m0.016s - -time ./tst_vector qvector_mutable_read_access -real 0m38.566s -user 0m36.754s -sys 0m0.008s - - -time ./tst_vector stdvector_mutable_read_access -real 0m12.736s -user 0m12.665s -sys 0m0.004s - - -//////////////////////////////////////////////////////////////////// - -time ./tst_vector qvector_fill_and_return -real 0m28.778s -user 0m28.522s -sys 0m0.012s - -time ./tst_vector stdvector_fill_and_return -real 0m26.675s -user 0m26.558s -sys 0m0.012s - -time ./tst_vector qrawvector_fill_and_return -real 0m23.370s -user 0m23.269s -sys 0m0.008s - - - -*/ - - - -#define TEST_RETURN 1 - -// For some reason, both 'plain' and '-callgrind' create strange results -// (like varying instruction count for the same assembly code) -// So replace it by a plain loop and measure wall clock time. -//#undef QBENCHMARK -//#define QBENCHMARK for (int j = 0; j != 10000; ++j) - -class tst_QVector: public QObject -{ - Q_OBJECT - -private slots: - void calibration(); - - // Pure Qt solution - void qvector_separator() { qWarning() << "QVector results: "; } - void qvector_const_read_access(); - void qvector_mutable_read_access(); - void qvector_pop_back(); - #ifdef TEST_RETURN - void qvector_fill_and_return(); - #endif - - // Purre Standard solution - void stdvector() { qWarning() << "std::vector results: "; } - void stdvector_const_read_access(); - void stdvector_mutable_read_access(); - void stdvector_pop_back(); - - #ifdef TEST_RETURN - void stdvector_fill_and_return(); - #endif - - // Build using std, pass as QVector - void mixedvector() { qWarning() << "mixed results: "; } - #ifdef TEST_RETURN - void mixedvector_fill_and_return(); - #endif - - // Alternative implementation - void qrawvector_separator() { qWarning() << "QRawVector results: "; } - void qrawvector_const_read_access(); - void qrawvector_mutable_read_access(); - #ifdef TEST_RETURN - void qrawvector_fill_and_return(); - #endif -}; - -const int N = 1000000; -extern double s; - -void tst_QVector::calibration() -{ - QVector<double> v(N); - for (int i = 0; i != N; ++i) - v[i] = i; - QBENCHMARK { - for (int i = 0; i != N; ++i) - s += i; - } -} - -///////////////////// QVector ///////////////////// - -void tst_QVector::qvector_const_read_access() -{ - QVector<double> v(N); - for (int i = 0; i != N; ++i) - v[i] = i; - - const QVector<double> &vc = v; - QBENCHMARK { - for (int i = 0; i != N; ++i) - s += vc[i]; - } -} - -void tst_QVector::qvector_mutable_read_access() -{ - QVector<double> v(N); - for (int i = 0; i != N; ++i) - v[i] = i; - - QBENCHMARK { - for (int i = 0; i != N; ++i) - s += v[i]; - } -} - -#ifdef TEST_RETURN -extern QVector<double> qvector_fill_and_return_helper(); - -void tst_QVector::qvector_fill_and_return() -{ - QBENCHMARK { - QVector<double> v = qvector_fill_and_return_helper(); - s += v[1]; - } -} - -#endif - - -///////////////////// QRawVector ///////////////////// - -void tst_QVector::qrawvector_const_read_access() -{ - QRawVector<double> v(N); - for (int i = 0; i != N; ++i) - v[i] = i; - - const QRawVector<double> &vc = v; - QBENCHMARK { - for (int i = vc.size(); --i >= 0;) - s += vc[i]; - } -} - -void tst_QVector::qrawvector_mutable_read_access() -{ - QRawVector<double> v(N); - for (int i = 0; i != N; ++i) - v[i] = i; - - QBENCHMARK { - for (int i = 0; i != N; ++i) - s += v[i]; - } -} - -void tst_QVector::qvector_pop_back() -{ - const int c1 = 100000; - QVERIFY(N % c1 == 0); - - QVector<int> v; - v.resize(N); - - QBENCHMARK { - for (int i = 0; i < c1; ++i) - v.pop_back(); - if (v.size() == 0) - v.resize(N); - } -} - - - -#ifdef TEST_RETURN -extern QVector<double> qrawvector_fill_and_return_helper(); - -void tst_QVector::qrawvector_fill_and_return() -{ - QBENCHMARK { - QVector<double> v = qrawvector_fill_and_return_helper(); - s += v[1]; - } -} - -#endif - - -///////////////////// std::vector ///////////////////// - -void tst_QVector::stdvector_const_read_access() -{ - std::vector<double> v(N); - for (int i = 0; i != N; ++i) - v[i] = i; - - const std::vector<double> &vc = v; - QBENCHMARK { - for (int i = 0; i != N; ++i) - s += vc[i]; - } -} - -void tst_QVector::stdvector_mutable_read_access() -{ - std::vector<double> v(N); - for (int i = 0; i != N; ++i) - v[i] = i; - - QBENCHMARK { - for (int i = 0; i != N; ++i) - s += v[i]; - } -} - -void tst_QVector::stdvector_pop_back() -{ - const int c1 = 100000; - QVERIFY(N % c1 == 0); - - std::vector<int> v; - v.resize(N); - - QBENCHMARK { - for (int i = 0; i < c1; ++i) - v.pop_back(); - if (v.size() == 0) - v.resize(N); - } -} - -#ifdef TEST_RETURN -extern std::vector<double> stdvector_fill_and_return_helper(); - -void tst_QVector::stdvector_fill_and_return() -{ - QBENCHMARK { - std::vector<double> v = stdvector_fill_and_return_helper(); - s += v[1]; - } -} - -#endif - -///////////////////// mixed vector ///////////////////// - - -#ifdef TEST_RETURN -extern QVector<double> mixedvector_fill_and_return_helper(); - -void tst_QVector::mixedvector_fill_and_return() -{ - QBENCHMARK { - std::vector<double> v = stdvector_fill_and_return_helper(); - s += v[1]; - } -} - -#endif - -QTEST_MAIN(tst_QVector) - -#include "main.moc" diff --git a/tests/benchmarks/corelib/tools/qvector/outofline.cpp b/tests/benchmarks/corelib/tools/qvector/outofline.cpp index daa630efe1..eb4756f710 100644 --- a/tests/benchmarks/corelib/tools/qvector/outofline.cpp +++ b/tests/benchmarks/corelib/tools/qvector/outofline.cpp @@ -1,58 +1,33 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtTest module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QList> -#include <vector> #include "qrawvector.h" +#include <vector> -const int N = 1000000; -double s = 0; +// Used as accumulator in tests: +double accumulate = 0; QVector<double> qvector_fill_and_return_helper() { - QVector<double> v(N); - for (int i = 0; i != N; ++i) + QVector<double> v(million); + for (int i = 0; i != million; ++i) v[i] = i; return v; } QVector<double> qrawvector_fill_and_return_helper() { - QRawVector<double> v(N); - for (int i = 0; i != N; ++i) + QRawVector<double> v(million); + for (int i = 0; i != million; ++i) v[i] = i; return v.mutateToVector(); } QVector<double> mixedvector_fill_and_return_helper() { - std::vector<double> v(N); - for (int i = 0; i != N; ++i) + std::vector<double> v(million); + for (int i = 0; i != million; ++i) v[i] = i; return QVector<double>(v.begin(), v.end()); } @@ -60,8 +35,8 @@ QVector<double> mixedvector_fill_and_return_helper() std::vector<double> stdvector_fill_and_return_helper() { - std::vector<double> v(N); - for (int i = 0; i != N; ++i) + std::vector<double> v(million); + for (int i = 0; i != million; ++i) v[i] = i; return v; } @@ -80,6 +55,8 @@ QVectorData *QVectorData::allocate(int size, int alignment) return static_cast<QVectorData *>(alignment > alignmentThreshold() ? qMallocAligned(size, alignment) : ::malloc(size)); } +QT_BEGIN_NAMESPACE + QVectorData *QVectorData::reallocate(QVectorData *x, int newsize, int oldsize, int alignment) { if (alignment > alignmentThreshold()) @@ -99,3 +76,5 @@ int QVectorData::grow(int sizeOfHeader, int size, int sizeOfT) { return qCalculateGrowingBlockSize(size, sizeOfT, sizeOfHeader).elementCount; } + +QT_END_NAMESPACE diff --git a/tests/benchmarks/corelib/tools/qvector/qrawvector.h b/tests/benchmarks/corelib/tools/qvector/qrawvector.h index 1f615f6e69..9e68b81285 100644 --- a/tests/benchmarks/corelib/tools/qvector/qrawvector.h +++ b/tests/benchmarks/corelib/tools/qvector/qrawvector.h @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #ifndef QRAWVECTOR_H #define QRAWVECTOR_H @@ -41,8 +16,16 @@ #include <stdlib.h> #include <string.h> -QT_BEGIN_NAMESPACE +const int million = 1000000; +extern double accumulate; + +// Defined in outofline.cpp +extern QVector<double> qvector_fill_and_return_helper(); +extern QVector<double> qrawvector_fill_and_return_helper(); +extern std::vector<double> stdvector_fill_and_return_helper(); +extern QVector<double> mixedvector_fill_and_return_helper(); +QT_BEGIN_NAMESPACE struct QVectorData { @@ -217,6 +200,7 @@ private: public: QVector<T> mutateToVector() { + Q_ASSERT(!"Fix QTBUG-95061 before calling this; it is broken beyond repair"); Data *d = toBase(m_begin); d->ref.initializeOwned(); d->alloc = m_alloc; diff --git a/tests/benchmarks/corelib/tools/qvector/qvector.pro b/tests/benchmarks/corelib/tools/qvector/qvector.pro deleted file mode 100644 index fce8a6cd78..0000000000 --- a/tests/benchmarks/corelib/tools/qvector/qvector.pro +++ /dev/null @@ -1,6 +0,0 @@ -CONFIG += benchmark -QT = core testlib core-private - -INCLUDEPATH += . -TARGET = tst_bench_vector -SOURCES += main.cpp outofline.cpp diff --git a/tests/benchmarks/corelib/tools/qvector/tst_bench_qvector.cpp b/tests/benchmarks/corelib/tools/qvector/tst_bench_qvector.cpp new file mode 100644 index 0000000000..0486beed4e --- /dev/null +++ b/tests/benchmarks/corelib/tools/qvector/tst_bench_qvector.cpp @@ -0,0 +1,228 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include <QVector> +#include <QDebug> +#include <QTest> + +#include "qrawvector.h" + +#include <vector> + +/* Using 'extern accumulate' causes some load making the loop resembling a + 'simple inner loop' in 'real' applications. +*/ + +/* QRawVector::mutateToVector() hacks a semblance of a Qt 5 QVector. + + However, Qt 6's QVector is Qt 6's QList and completely different in internal + layout. The QTypedArrayData inside it is also completely rearranged. Until + QRawVector can be rewritten to do whatever it's supposed to do in a + Qt6-compatible way, this test is suppressed, see QTBUG-95061. +*/ +#define TEST_RAW 0 + +// TODO: is this still a thing ? (Dates from g++ 4.3.3 in 2009.) +// For some reason, both 'plain' and '-callgrind' create strange results +// (like varying instruction count for the same assembly code) +// So replace it by a plain loop and measure wall clock time. +//#undef QBENCHMARK +//#define QBENCHMARK for (int j = 0; j != 10000; ++j) + +class tst_QVector: public QObject +{ + Q_OBJECT + +private slots: + void calibration(); + + // Pure Qt solution + void qvector_separator() { qWarning() << "QVector results: "; } + void qvector_const_read_access(); + void qvector_mutable_read_access(); + void qvector_pop_back(); + void qvector_fill_and_return(); + + // Purre Standard solution + void stdvector() { qWarning() << "std::vector results: "; } + void stdvector_const_read_access(); + void stdvector_mutable_read_access(); + void stdvector_pop_back(); + void stdvector_fill_and_return(); + + // Build using std, pass as QVector + void mixedvector() { qWarning() << "mixed results: "; } + void mixedvector_fill_and_return(); + + // Alternative implementation + void qrawvector_separator() { qWarning() << "QRawVector results: "; } + void qrawvector_const_read_access(); + void qrawvector_mutable_read_access(); +#if TEST_RAW + void qrawvector_fill_and_return(); +#endif +}; + +void tst_QVector::calibration() +{ + QVector<double> v(million); + for (int i = 0; i < million; ++i) + v[i] = i; + QBENCHMARK { + for (int i = 0; i < million; ++i) + accumulate += i; + } +} + +///////////////////// QVector ///////////////////// + +void tst_QVector::qvector_const_read_access() +{ + QVector<double> v(million); + for (int i = 0; i < million; ++i) + v[i] = i; + + const QVector<double> &vc = v; + QBENCHMARK { + for (int i = 0; i < million; ++i) + accumulate += vc[i]; + } +} + +void tst_QVector::qvector_mutable_read_access() +{ + QVector<double> v(million); + for (int i = 0; i < million; ++i) + v[i] = i; + + QBENCHMARK { + for (int i = 0; i < million; ++i) + accumulate += v[i]; + } +} + +void tst_QVector::qvector_fill_and_return() +{ + QBENCHMARK { + QVector<double> v = qvector_fill_and_return_helper(); + accumulate += v[1]; + } +} + +///////////////////// QRawVector ///////////////////// + +void tst_QVector::qrawvector_const_read_access() +{ + QRawVector<double> v(million); + for (int i = 0; i < million; ++i) + v[i] = i; + + const QRawVector<double> &vc = v; + QBENCHMARK { + for (int i = vc.size(); --i >= 0;) + accumulate += vc[i]; + } +} + +void tst_QVector::qrawvector_mutable_read_access() +{ + QRawVector<double> v(million); + for (int i = 0; i < million; ++i) + v[i] = i; + + QBENCHMARK { + for (int i = 0; i < million; ++i) + accumulate += v[i]; + } +} + +void tst_QVector::qvector_pop_back() +{ + const int c1 = 100000; + QVERIFY(million % c1 == 0); + + QVector<int> v; + v.resize(million); + + QBENCHMARK { + for (int i = 0; i < c1; ++i) + v.pop_back(); + if (v.size() == 0) + v.resize(million); + } +} + +#if TEST_RAW +void tst_QVector::qrawvector_fill_and_return() +{ + QBENCHMARK { + QVector<double> v = qrawvector_fill_and_return_helper(); + accumulate += v[1]; + } +} +#endif + +///////////////////// std::vector ///////////////////// + +void tst_QVector::stdvector_const_read_access() +{ + std::vector<double> v(million); + for (int i = 0; i < million; ++i) + v[i] = i; + + const std::vector<double> &vc = v; + QBENCHMARK { + for (int i = 0; i < million; ++i) + accumulate += vc[i]; + } +} + +void tst_QVector::stdvector_mutable_read_access() +{ + std::vector<double> v(million); + for (int i = 0; i < million; ++i) + v[i] = i; + + QBENCHMARK { + for (int i = 0; i < million; ++i) + accumulate += v[i]; + } +} + +void tst_QVector::stdvector_pop_back() +{ + const int size = million / 10; + QVERIFY(million % size == 0); + + std::vector<int> v; + v.resize(million); + + QBENCHMARK { + for (int i = 0; i < size; ++i) + v.pop_back(); + if (v.size() == 0) + v.resize(million); + } +} + +void tst_QVector::stdvector_fill_and_return() +{ + QBENCHMARK { + std::vector<double> v = stdvector_fill_and_return_helper(); + accumulate += v[1]; + } +} + +///////////////////// mixed vector ///////////////////// + +void tst_QVector::mixedvector_fill_and_return() +{ + QBENCHMARK { + std::vector<double> v = stdvector_fill_and_return_helper(); + accumulate += v[1]; + } +} + +QTEST_MAIN(tst_QVector) + +#include "tst_bench_qvector.moc" diff --git a/tests/benchmarks/corelib/tools/tools.pro b/tests/benchmarks/corelib/tools/tools.pro deleted file mode 100644 index 8abb9feefb..0000000000 --- a/tests/benchmarks/corelib/tools/tools.pro +++ /dev/null @@ -1,12 +0,0 @@ -TEMPLATE = subdirs -SUBDIRS = \ - containers-associative \ - containers-sequential \ - qcontiguouscache \ - qcryptographichash \ - qlist \ - qmap \ - qrect \ - qringbuffer \ - qstack \ - qvector |