diff options
Diffstat (limited to 'tests/benchmarks/widgets/itemviews')
5 files changed, 642 insertions, 0 deletions
diff --git a/tests/benchmarks/widgets/itemviews/itemviews.pro b/tests/benchmarks/widgets/itemviews/itemviews.pro new file mode 100644 index 0000000000..a23cdf7b97 --- /dev/null +++ b/tests/benchmarks/widgets/itemviews/itemviews.pro @@ -0,0 +1,4 @@ +TEMPLATE = subdirs +SUBDIRS = \ + qtableview \ + qheaderview diff --git a/tests/benchmarks/widgets/itemviews/qheaderview/qheaderview.pro b/tests/benchmarks/widgets/itemviews/qheaderview/qheaderview.pro new file mode 100644 index 0000000000..7e8415e495 --- /dev/null +++ b/tests/benchmarks/widgets/itemviews/qheaderview/qheaderview.pro @@ -0,0 +1,7 @@ +QT += widgets testlib + +TEMPLATE = app +TARGET = tst_bench_qheaderview + +SOURCES += qheaderviewbench.cpp + diff --git a/tests/benchmarks/widgets/itemviews/qheaderview/qheaderviewbench.cpp b/tests/benchmarks/widgets/itemviews/qheaderview/qheaderviewbench.cpp new file mode 100644 index 0000000000..49ce060580 --- /dev/null +++ b/tests/benchmarks/widgets/itemviews/qheaderview/qheaderviewbench.cpp @@ -0,0 +1,251 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Thorbjørn Lund Martsum - tmartsum[at]gmail.com +** 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 <QtTest/QtTest> +#include <QtWidgets/QtWidgets> + +class BenchQHeaderView : public QObject +{ + Q_OBJECT +public: + BenchQHeaderView() : QObject() {m_tv = 0; m_hv = 0; m_model = 0;} + +protected: + QTableView *m_tv; + QHeaderView *m_hv; + QStandardItemModel *m_model; + QStandardItemModel m_normalmodel; + QElapsedTimer t; + bool m_worst_case; + void setupTestData(); + + bool m_blockSomeSignals; + bool m_updatesEnabled; + int m_rowcount; + int m_colcount; + + +private slots: + void init(); + void cleanupTestCase(); + void initTestCase(); + void cleanup(); + void visualIndexAtSpecial_data() {setupTestData();} + void visualIndexAt_data() {setupTestData();} + void hideShowBench_data() {setupTestData();} + void swapSectionsBench_data() {setupTestData();} + void moveSectionBench_data() {setupTestData();} + void defaultSizeBench_data() {setupTestData();} + void removeBench_data() {setupTestData();} + void insertBench_data() {setupTestData();} + void truncBench_data() {setupTestData();} + + void visualIndexAtSpecial(); + void visualIndexAt(); + void hideShowBench(); + void swapSectionsBench(); + void moveSectionBench(); + void defaultSizeBench(); + void removeBench(); + void insertBench(); + void truncBench(); +}; + +void BenchQHeaderView::setupTestData() +{ + QTest::addColumn<bool>("worst_case"); + QTest::newRow("Less relevant best case") << false; + QTest::newRow("__* More important worst case *__") << true; +} + +void BenchQHeaderView::initTestCase() +{ + m_tv = new QTableView(); + m_hv = m_tv->verticalHeader(); + m_model = &m_normalmodel; + m_tv->setModel(m_model); + m_tv->show(); +} + +void BenchQHeaderView::cleanupTestCase() +{ + delete m_tv; + m_tv = 0; + m_hv = 0; +} + +void BenchQHeaderView::init() +{ + QFETCH(bool, worst_case); + + m_blockSomeSignals = true; + m_updatesEnabled = false; + m_rowcount = 2500; + m_colcount = 10; + + m_worst_case = worst_case; + m_model->clear(); + if (worst_case) { + for (int u = 0; u <= m_rowcount; ++u) // ensures fragment in Qt 4.x + m_model->setRowCount(u); + m_model->setColumnCount(m_colcount); + m_hv->swapSections(0, m_rowcount - 1); + m_hv->hideSection(m_rowcount / 2); + } else { + m_model->setColumnCount(m_colcount); + m_model->setRowCount(m_rowcount); + } + + QString s; + for (int i = 0; i < m_model->rowCount(); ++i) { + m_model->setData(m_model->index(i, 0), QVariant(i)); + s.setNum(i); + s += QLatin1Char('.'); + s += 'a' + (i % 25); + m_model->setData(m_model->index(i, 1), QVariant(s)); + } + m_tv->setUpdatesEnabled(m_updatesEnabled); + m_hv->blockSignals(m_blockSomeSignals); + + const int default_section_size = 25; + m_hv->setDefaultSectionSize(default_section_size); +} + +void BenchQHeaderView::cleanup() +{ + m_tv->setUpdatesEnabled(true); + m_hv->blockSignals(false); +} + +void BenchQHeaderView::visualIndexAtSpecial() +{ + int lookup_pos = m_hv->length() - 50; + int testnum = 0; + + QBENCHMARK { + ++testnum; + m_hv->resizeSection(0, testnum % 47); + m_hv->visualIndexAt(lookup_pos); + } +} + +void BenchQHeaderView::visualIndexAt() +{ + const int center_pos = m_hv->length() / 2; + const int maxpos = m_hv->length() - 1; + + QBENCHMARK { + m_hv->visualIndexAt(0); + m_hv->visualIndexAt(center_pos); + m_hv->visualIndexAt(maxpos); + } +} + +void BenchQHeaderView::hideShowBench() +{ + int n = 0; + bool hide_set = true; + + QBENCHMARK { + m_hv->setSectionHidden(n, hide_set); + if (n >= m_hv->count()) { + n = -1; + hide_set = !hide_set; + } + ++n; + } +} + +void BenchQHeaderView::swapSectionsBench() +{ + int n = 0; + QBENCHMARK { + m_hv->swapSections(n, n + 1); + if (++n >= m_hv->count()) + n = 0; + } +} + +void BenchQHeaderView::moveSectionBench() +{ + QBENCHMARK { + m_hv->moveSection(0, m_hv->count() - 2); + } +} + +void BenchQHeaderView::defaultSizeBench() +{ + int n = 1; + QBENCHMARK { + m_hv->setDefaultSectionSize(n); + ++n; + } +} + +void BenchQHeaderView::removeBench() +{ + QBENCHMARK { + m_model->removeRows(0, 1); + if (m_hv->count() == 0) { // setup a new hard model + m_model->setRowCount(m_rowcount); + if (m_worst_case) { + m_hv->swapSections(0, m_rowcount - 1); + m_hv->hideSection(m_rowcount / 2); + } + } + } +} + +void BenchQHeaderView::insertBench() +{ + QBENCHMARK { + m_model->insertRows(1, 1); + if (m_hv->count() == 10000000) { // setup a new hard model + m_model->setRowCount(m_rowcount); + if (m_worst_case) { + m_hv->swapSections(0, m_rowcount - 1); + m_hv->hideSection(m_rowcount / 2); + } + } + } +} + +void BenchQHeaderView::truncBench() +{ + QBENCHMARK { + m_model->setRowCount(1); + m_model->setRowCount(m_rowcount); + if (m_worst_case) { + m_hv->swapSections(0, m_rowcount - 1); + m_hv->hideSection(m_rowcount / 2); + } + } +} + +QTEST_MAIN(BenchQHeaderView) +#include "qheaderviewbench.moc" diff --git a/tests/benchmarks/widgets/itemviews/qtableview/qtableview.pro b/tests/benchmarks/widgets/itemviews/qtableview/qtableview.pro new file mode 100644 index 0000000000..bd2306d646 --- /dev/null +++ b/tests/benchmarks/widgets/itemviews/qtableview/qtableview.pro @@ -0,0 +1,7 @@ +QT += widgets testlib + +TEMPLATE = app +TARGET = tst_bench_qtableview + +SOURCES += tst_qtableview.cpp + diff --git a/tests/benchmarks/widgets/itemviews/qtableview/tst_qtableview.cpp b/tests/benchmarks/widgets/itemviews/qtableview/tst_qtableview.cpp new file mode 100644 index 0000000000..9ce214e5ff --- /dev/null +++ b/tests/benchmarks/widgets/itemviews/qtableview/tst_qtableview.cpp @@ -0,0 +1,373 @@ +/**************************************************************************** +** +** 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 <qtest.h> +#include <QDebug> +#include <QTableView> +#include <QImage> +#include <QPainter> +#include <QHeaderView> +#include <QStandardItemModel> + +class QtTestTableModel: public QAbstractTableModel +{ + Q_OBJECT + + +public: + QtTestTableModel(int rows = 0, int columns = 0, QObject *parent = 0) + : QAbstractTableModel(parent), + row_count(rows), + column_count(columns) {} + + int rowCount(const QModelIndex& = QModelIndex()) const { return row_count; } + int columnCount(const QModelIndex& = QModelIndex()) const { return column_count; } + bool isEditable(const QModelIndex &) const { return true; } + + QVariant data(const QModelIndex &idx, int role) const + { + if (!idx.isValid() || idx.row() >= row_count || idx.column() >= column_count) { + qWarning() << "Invalid modelIndex [%d,%d,%p]" << idx; + return QVariant(); + } + + if (role == Qt::DisplayRole || role == Qt::EditRole) + return QString("[%1,%2,%3]").arg(idx.row()).arg(idx.column()).arg(0); + + return QVariant(); + } + + bool insertRows(int start, int count, const QModelIndex &parent = QModelIndex()) + { + if (start < 0 || start > row_count) + return false; + + beginInsertRows(parent, start, start + count - 1); + row_count += count; + endInsertRows(); + return true; + } + + bool removeRows(int start, int count, const QModelIndex &parent = QModelIndex()) + { + if (start < 0 || start >= row_count || row_count < count) + return false; + + beginRemoveRows(parent, start, start + count - 1); + row_count -= count; + endRemoveRows(); + return true; + } + + bool insertColumns(int start, int count, const QModelIndex &parent = QModelIndex()) + { + if (start < 0 || start > column_count) + return false; + + beginInsertColumns(parent, start, start + count - 1); + column_count += count; + endInsertColumns(); + return true; + } + + bool removeColumns(int start, int count, const QModelIndex &parent = QModelIndex()) + { + if (start < 0 || start >= column_count || column_count < count) + return false; + + beginRemoveColumns(parent, start, start + count - 1); + column_count -= count; + endRemoveColumns(); + return true; + } + + int row_count; + int column_count; +}; + + + + +class tst_QTableView : public QObject +{ + Q_OBJECT + +public: + tst_QTableView(); + virtual ~tst_QTableView(); + +public slots: + void init(); + void cleanup(); + +private slots: + void spanInit(); + void spanDraw(); + void spanSelectColumn(); + void spanSelectAll(); + void rowInsertion_data(); + void rowInsertion(); + void rowRemoval_data(); + void rowRemoval(); + void columnInsertion_data(); + void columnInsertion(); + void columnRemoval_data(); + void columnRemoval(); + void sizeHintForColumnWhenHidden(); +private: + static inline void spanInit_helper(QTableView *); +}; + +tst_QTableView::tst_QTableView() +{ +} + +tst_QTableView::~tst_QTableView() +{ +} + +void tst_QTableView::init() +{ +} + +void tst_QTableView::cleanup() +{ +} + +void tst_QTableView::spanInit_helper(QTableView *view) +{ + for (int i=0; i < 40; i++) { + view->setSpan(1+i%2, 1+4*i, 1+i%3, 2); + } + + for (int i=1; i < 40; i++) { + view->setSpan(6 + i*7, 4, 4, 50); + } +} + +void tst_QTableView::spanInit() +{ + QtTestTableModel model(500, 500); + QTableView v; + v.setModel(&model); + + QBENCHMARK { + spanInit_helper(&v); + } +} + +void tst_QTableView::spanDraw() +{ + QtTestTableModel model(500, 500); + QTableView v; + v.setModel(&model); + + spanInit_helper(&v); + v.show(); + v.resize(500,500); + QTest::qWait(30); + + QImage image(500, 500, QImage::Format_ARGB32_Premultiplied); + QPainter painter(&image); + QBENCHMARK { + v.render(&painter); + } +} + +void tst_QTableView::spanSelectAll() +{ + QtTestTableModel model(500, 500); + QTableView v; + v.setModel(&model); + + spanInit_helper(&v); + v.show(); + QTest::qWait(30); + + QBENCHMARK { + v.selectAll(); + } +} + +void tst_QTableView::spanSelectColumn() +{ + QtTestTableModel model(500, 500); + QTableView v; + v.setModel(&model); + + spanInit_helper(&v); + v.show(); + QTest::qWait(30); + + QBENCHMARK { + v.selectColumn(22); + } +} + +typedef QVector<QRect> SpanList; +Q_DECLARE_METATYPE(SpanList) + +void spansData() +{ + QTest::addColumn<SpanList>("spans"); + + QTest::newRow("Without spans") + << SpanList(); + + QTest::newRow("With spans") + << (SpanList() + << QRect(0, 1, 1, 2) + << QRect(1, 2, 1, 2) + << QRect(2, 2, 1, 5) + << QRect(2, 8, 1, 2) + << QRect(3, 4, 1, 2) + << QRect(4, 4, 1, 4) + << QRect(5, 6, 1, 3) + << QRect(6, 7, 1, 3)); +} + +void tst_QTableView::rowInsertion_data() +{ + spansData(); +} + +void tst_QTableView::rowInsertion() +{ + QFETCH(SpanList, spans); + + QtTestTableModel model(10, 10); + QTableView view; + view.setModel(&model); + + foreach (QRect span, spans) + view.setSpan(span.top(), span.left(), span.height(), span.width()); + view.show(); + QTest::qWait(50); + + QBENCHMARK_ONCE { + view.model()->insertRows(0, 2); + view.model()->insertRows(5, 2); + view.model()->insertRows(8, 2); + view.model()->insertRows(12, 2); + } +} + +void tst_QTableView::rowRemoval_data() +{ + spansData(); +} + +void tst_QTableView::rowRemoval() +{ + QFETCH(SpanList, spans); + + QtTestTableModel model(10, 10); + QTableView view; + view.setModel(&model); + + foreach (QRect span, spans) + view.setSpan(span.top(), span.left(), span.height(), span.width()); + view.show(); + QTest::qWait(50); + + QBENCHMARK_ONCE { + view.model()->removeRows(3, 3); + } +} + +void tst_QTableView::columnInsertion_data() +{ + spansData(); +} + +void tst_QTableView::columnInsertion() +{ + QFETCH(SpanList, spans); + + QtTestTableModel model(10, 10); + QTableView view; + view.setModel(&model); + + // Same set as for rowInsertion, just swapping columns and rows. + foreach (QRect span, spans) + view.setSpan(span.left(), span.top(), span.width(), span.height()); + view.show(); + QTest::qWait(50); + + QBENCHMARK_ONCE { + view.model()->insertColumns(0, 2); + view.model()->insertColumns(5, 2); + view.model()->insertColumns(8, 2); + view.model()->insertColumns(12, 2); + } +} + +void tst_QTableView::columnRemoval_data() +{ + spansData(); +} + +void tst_QTableView::columnRemoval() +{ + QFETCH(SpanList, spans); + + QtTestTableModel model(10, 10); + QTableView view; + view.setModel(&model); + + // Same set as for rowRemoval, just swapping columns and rows. + foreach (QRect span, spans) + view.setSpan(span.left(), span.top(), span.width(), span.height()); + view.show(); + QTest::qWait(50); + + QBENCHMARK_ONCE { + view.model()->removeColumns(3, 3); + } +} + +void tst_QTableView::sizeHintForColumnWhenHidden() +{ + QTableView view; + QStandardItemModel model(12500, 6); + for (int r = 0; r < model.rowCount(); ++r) + for (int c = 0; c < model.columnCount(); ++c) { + QStandardItem *item = new QStandardItem(QString("row %0, column %1").arg(r).arg(c)); + model.setItem(r, c, item); + } + + view.horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); + view.setModel(&model); + QBENCHMARK_ONCE { + view.horizontalHeader()->resizeSection(0, 10); // this force resizeSections - on a hidden view. + } + +} + +QTEST_MAIN(tst_QTableView) +#include "tst_qtableview.moc" |