diff options
Diffstat (limited to 'tests/benchmarks/corelib/tools/qvector')
-rw-r--r-- | tests/benchmarks/corelib/tools/qvector/CMakeLists.txt | 11 | ||||
-rw-r--r-- | tests/benchmarks/corelib/tools/qvector/main.cpp | 414 | ||||
-rw-r--r-- | tests/benchmarks/corelib/tools/qvector/outofline.cpp | 55 | ||||
-rw-r--r-- | tests/benchmarks/corelib/tools/qvector/qrawvector.h | 40 | ||||
-rw-r--r-- | tests/benchmarks/corelib/tools/qvector/tst_bench_qvector.cpp | 228 |
5 files changed, 263 insertions, 485 deletions
diff --git a/tests/benchmarks/corelib/tools/qvector/CMakeLists.txt b/tests/benchmarks/corelib/tools/qvector/CMakeLists.txt index 467405eea0..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_internal_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 b090c04480..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 <QTest> - -#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/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" |