mirror of
https://github.com/crystalidea/qt6windows7.git
synced 2025-07-04 00:05:25 +08:00
qt 6.5.1 original
This commit is contained in:
17
tests/benchmarks/corelib/kernel/CMakeLists.txt
Normal file
17
tests/benchmarks/corelib/kernel/CMakeLists.txt
Normal file
@ -0,0 +1,17 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
add_subdirectory(events)
|
||||
add_subdirectory(qmetatype)
|
||||
add_subdirectory(qvariant)
|
||||
add_subdirectory(qcoreapplication)
|
||||
add_subdirectory(qtimer_vs_qmetaobject)
|
||||
add_subdirectory(qproperty)
|
||||
add_subdirectory(qmetaenum)
|
||||
if(TARGET Qt::Widgets)
|
||||
add_subdirectory(qmetaobject)
|
||||
add_subdirectory(qobject)
|
||||
endif()
|
||||
if(WIN32)
|
||||
add_subdirectory(qwineventnotifier)
|
||||
endif()
|
13
tests/benchmarks/corelib/kernel/events/CMakeLists.txt
Normal file
13
tests/benchmarks/corelib/kernel/events/CMakeLists.txt
Normal file
@ -0,0 +1,13 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_bench_events Binary:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_benchmark(tst_bench_events
|
||||
SOURCES
|
||||
tst_bench_events.cpp
|
||||
LIBRARIES
|
||||
Qt::Test
|
||||
)
|
150
tests/benchmarks/corelib/kernel/events/tst_bench_events.cpp
Normal file
150
tests/benchmarks/corelib/kernel/events/tst_bench_events.cpp
Normal file
@ -0,0 +1,150 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
#include <QtCore>
|
||||
|
||||
#include <qtest.h>
|
||||
#include <qtesteventloop.h>
|
||||
|
||||
class PingPong : public QObject
|
||||
{
|
||||
public:
|
||||
void setPeer(QObject *peer);
|
||||
void resetCounter() {m_counter = 100;}
|
||||
|
||||
protected:
|
||||
bool event(QEvent *e) override;
|
||||
|
||||
private:
|
||||
QObject *m_peer;
|
||||
int m_counter;
|
||||
};
|
||||
|
||||
void PingPong::setPeer(QObject *peer)
|
||||
{
|
||||
m_peer = peer;
|
||||
m_counter = 100;
|
||||
}
|
||||
|
||||
bool PingPong::event(QEvent *)
|
||||
{
|
||||
--m_counter;
|
||||
if (m_counter > 0) {
|
||||
QEvent *e = new QEvent(QEvent::User);
|
||||
QCoreApplication::postEvent(m_peer, e);
|
||||
} else {
|
||||
QTestEventLoop::instance().exitLoop();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
class EventTester : public QObject
|
||||
{
|
||||
public:
|
||||
int foo(int bar);
|
||||
|
||||
protected:
|
||||
bool event(QEvent *e) override;
|
||||
};
|
||||
|
||||
bool EventTester::event(QEvent *e)
|
||||
{
|
||||
if (e->type() == QEvent::User+1)
|
||||
return foo(e->type()) != 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
int EventTester::foo(int bar)
|
||||
{
|
||||
return bar + 1;
|
||||
}
|
||||
|
||||
class EventsBench : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void initTestCase();
|
||||
void cleanupTestCase();
|
||||
|
||||
void noEvent();
|
||||
void sendEvent_data();
|
||||
void sendEvent();
|
||||
void postEvent_data();
|
||||
void postEvent();
|
||||
};
|
||||
|
||||
void EventsBench::initTestCase()
|
||||
{
|
||||
}
|
||||
|
||||
void EventsBench::cleanupTestCase()
|
||||
{
|
||||
}
|
||||
|
||||
void EventsBench::noEvent()
|
||||
{
|
||||
EventTester tst;
|
||||
int val = 0;
|
||||
QBENCHMARK {
|
||||
val += tst.foo(1);
|
||||
}
|
||||
QVERIFY(val > 0);
|
||||
}
|
||||
|
||||
void EventsBench::sendEvent_data()
|
||||
{
|
||||
QTest::addColumn<bool>("filterEvents");
|
||||
QTest::newRow("no eventfilter") << false;
|
||||
QTest::newRow("eventfilter") << true;
|
||||
}
|
||||
|
||||
void EventsBench::sendEvent()
|
||||
{
|
||||
QFETCH(bool, filterEvents);
|
||||
EventTester tst;
|
||||
if (filterEvents)
|
||||
tst.installEventFilter(this);
|
||||
QEvent evt(QEvent::Type(QEvent::User+1));
|
||||
QBENCHMARK {
|
||||
QCoreApplication::sendEvent(&tst, &evt);
|
||||
}
|
||||
}
|
||||
|
||||
void EventsBench::postEvent_data()
|
||||
{
|
||||
QTest::addColumn<bool>("filterEvents");
|
||||
// The first time an eventloop is executed, the case runs radically slower at least
|
||||
// on some platforms, so test the "no eventfilter" case to get a comparable results
|
||||
// with the "eventfilter" case.
|
||||
QTest::newRow("first time, no eventfilter") << false;
|
||||
QTest::newRow("no eventfilter") << false;
|
||||
QTest::newRow("eventfilter") << true;
|
||||
}
|
||||
|
||||
void EventsBench::postEvent()
|
||||
{
|
||||
QFETCH(bool, filterEvents);
|
||||
PingPong ping;
|
||||
PingPong pong;
|
||||
ping.setPeer(&pong);
|
||||
pong.setPeer(&ping);
|
||||
if (filterEvents) {
|
||||
ping.installEventFilter(this);
|
||||
pong.installEventFilter(this);
|
||||
}
|
||||
|
||||
QBENCHMARK {
|
||||
// In case multiple iterations are done, event needs to be created inside the QBENCHMARK,
|
||||
// or it gets deleted once first iteration exits and can cause a crash. Similarly,
|
||||
// ping and pong need their counters reset.
|
||||
QEvent *e = new QEvent(QEvent::User);
|
||||
ping.resetCounter();
|
||||
pong.resetCounter();
|
||||
QCoreApplication::postEvent(&ping, e);
|
||||
QTestEventLoop::instance().enterLoop( 61 );
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(EventsBench)
|
||||
|
||||
#include "tst_bench_events.moc"
|
@ -0,0 +1,13 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_bench_qcoreapplication Binary:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_benchmark(tst_bench_qcoreapplication
|
||||
SOURCES
|
||||
tst_bench_qcoreapplication.cpp
|
||||
LIBRARIES
|
||||
Qt::Test
|
||||
)
|
@ -0,0 +1,44 @@
|
||||
// Copyright (C) 2011 Robin Burchell <robin+qt@viroteck.net>
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
#include <QtCore>
|
||||
#include <qtest.h>
|
||||
#include <qcoreapplication.h>
|
||||
|
||||
class tst_QCoreApplication : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void event_posting_benchmark_data();
|
||||
void event_posting_benchmark();
|
||||
};
|
||||
|
||||
void tst_QCoreApplication::event_posting_benchmark_data()
|
||||
{
|
||||
QTest::addColumn<int>("size");
|
||||
QTest::newRow("50 events") << 50;
|
||||
QTest::newRow("100 events") << 100;
|
||||
QTest::newRow("200 events") << 200;
|
||||
QTest::newRow("1000 events") << 1000;
|
||||
QTest::newRow("10000 events") << 10000;
|
||||
QTest::newRow("100000 events") << 100000;
|
||||
QTest::newRow("1000000 events") << 1000000;
|
||||
}
|
||||
|
||||
void tst_QCoreApplication::event_posting_benchmark()
|
||||
{
|
||||
QFETCH(int, size);
|
||||
|
||||
int type = QEvent::registerEventType();
|
||||
QCoreApplication *app = QCoreApplication::instance();
|
||||
|
||||
// benchmark posting & sending events
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < size; ++i)
|
||||
QCoreApplication::postEvent(app, new QEvent(QEvent::Type(type)));
|
||||
QCoreApplication::sendPostedEvents();
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QCoreApplication)
|
||||
|
||||
#include "tst_bench_qcoreapplication.moc"
|
10
tests/benchmarks/corelib/kernel/qmetaenum/CMakeLists.txt
Normal file
10
tests/benchmarks/corelib/kernel/qmetaenum/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
qt_internal_add_benchmark(tst_bench_qmetaenum
|
||||
SOURCES
|
||||
tst_bench_qmetaenum.cpp
|
||||
LIBRARIES
|
||||
Qt::Core
|
||||
Qt::Test
|
||||
)
|
@ -0,0 +1,55 @@
|
||||
// Copyright (C) 2021 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <QMetaEnum>
|
||||
#include <QTest>
|
||||
|
||||
class tst_QMetaEnum: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
using QObject::QObject;
|
||||
|
||||
private Q_SLOTS:
|
||||
void valueToKeys_data();
|
||||
void valueToKeys();
|
||||
void keysToValue_data() { valueToKeys_data(); }
|
||||
void keysToValue();
|
||||
};
|
||||
|
||||
void tst_QMetaEnum::valueToKeys_data()
|
||||
{
|
||||
QTest::addColumn<int>("buttons");
|
||||
QTest::addColumn<QByteArray>("string");
|
||||
// Qt::MouseButtons has at least 24 enumerators, so it's a good performance test
|
||||
const auto me = QMetaEnum::fromType<Qt::MouseButtons>();
|
||||
int accu = 0;
|
||||
for (int i = 0; i < std::min(31, me.keyCount()); ++i) {
|
||||
accu <<= 1;
|
||||
accu |= 1;
|
||||
QTest::addRow("%d bits set", i) << accu << me.valueToKeys(accu);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaEnum::valueToKeys()
|
||||
{
|
||||
QFETCH(const int, buttons);
|
||||
const auto me = QMetaEnum::fromType<Qt::MouseButtons>();
|
||||
QBENCHMARK {
|
||||
[[maybe_unused]] auto r = me.valueToKeys(buttons);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaEnum::keysToValue()
|
||||
{
|
||||
QFETCH(const QByteArray, string);
|
||||
const auto me = QMetaEnum::fromType<Qt::MouseButtons>();
|
||||
bool ok;
|
||||
QBENCHMARK {
|
||||
[[maybe_unused]] auto r = me.keysToValue(string.data(), &ok);
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QMetaEnum)
|
||||
|
||||
#include "tst_bench_qmetaenum.moc"
|
15
tests/benchmarks/corelib/kernel/qmetaobject/CMakeLists.txt
Normal file
15
tests/benchmarks/corelib/kernel/qmetaobject/CMakeLists.txt
Normal file
@ -0,0 +1,15 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_bench_qmetaobject Binary:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_benchmark(tst_bench_qmetaobject
|
||||
SOURCES
|
||||
tst_bench_qmetaobject.cpp
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::Test
|
||||
Qt::Widgets
|
||||
)
|
@ -0,0 +1,216 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
#include <QtCore>
|
||||
#include <QtWidgets/QTreeView>
|
||||
#include <qtest.h>
|
||||
|
||||
class LotsOfSignals : public QObject // for the unconnected() test
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
LotsOfSignals() {}
|
||||
|
||||
signals:
|
||||
void extraSignal1();
|
||||
void extraSignal2();
|
||||
void extraSignal3();
|
||||
void extraSignal4();
|
||||
void extraSignal5();
|
||||
void extraSignal6();
|
||||
void extraSignal7();
|
||||
void extraSignal8();
|
||||
void extraSignal9();
|
||||
void extraSignal10();
|
||||
void extraSignal12();
|
||||
void extraSignal13();
|
||||
void extraSignal14();
|
||||
void extraSignal15();
|
||||
void extraSignal16();
|
||||
void extraSignal17();
|
||||
void extraSignal18();
|
||||
void extraSignal19();
|
||||
void extraSignal20();
|
||||
void extraSignal21();
|
||||
void extraSignal22();
|
||||
void extraSignal23();
|
||||
void extraSignal24();
|
||||
void extraSignal25();
|
||||
void extraSignal26();
|
||||
void extraSignal27();
|
||||
void extraSignal28();
|
||||
void extraSignal29();
|
||||
void extraSignal30();
|
||||
void extraSignal31();
|
||||
void extraSignal32();
|
||||
void extraSignal33();
|
||||
void extraSignal34();
|
||||
void extraSignal35();
|
||||
void extraSignal36();
|
||||
void extraSignal37();
|
||||
void extraSignal38();
|
||||
void extraSignal39();
|
||||
void extraSignal40();
|
||||
void extraSignal41();
|
||||
void extraSignal42();
|
||||
void extraSignal43();
|
||||
void extraSignal44();
|
||||
void extraSignal45();
|
||||
void extraSignal46();
|
||||
void extraSignal47();
|
||||
void extraSignal48();
|
||||
void extraSignal49();
|
||||
void extraSignal50();
|
||||
void extraSignal51();
|
||||
void extraSignal52();
|
||||
void extraSignal53();
|
||||
void extraSignal54();
|
||||
void extraSignal55();
|
||||
void extraSignal56();
|
||||
void extraSignal57();
|
||||
void extraSignal58();
|
||||
void extraSignal59();
|
||||
void extraSignal60();
|
||||
void extraSignal61();
|
||||
void extraSignal62();
|
||||
void extraSignal63();
|
||||
void extraSignal64();
|
||||
void extraSignal65();
|
||||
void extraSignal66();
|
||||
void extraSignal67();
|
||||
void extraSignal68();
|
||||
void extraSignal69();
|
||||
void extraSignal70();
|
||||
};
|
||||
|
||||
class tst_QMetaObject: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void indexOfProperty_data();
|
||||
void indexOfProperty();
|
||||
void indexOfMethod_data();
|
||||
void indexOfMethod();
|
||||
void indexOfSignal_data();
|
||||
void indexOfSignal();
|
||||
void indexOfSlot_data();
|
||||
void indexOfSlot();
|
||||
|
||||
void unconnected_data();
|
||||
void unconnected();
|
||||
};
|
||||
|
||||
void tst_QMetaObject::indexOfProperty_data()
|
||||
{
|
||||
QTest::addColumn<QByteArray>("name");
|
||||
const QMetaObject *mo = &QTreeView::staticMetaObject;
|
||||
for (int i = 0; i < mo->propertyCount(); ++i) {
|
||||
QMetaProperty prop = mo->property(i);
|
||||
QTest::newRow(prop.name()) << QByteArray(prop.name());
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaObject::indexOfProperty()
|
||||
{
|
||||
QFETCH(QByteArray, name);
|
||||
const char *p = name.constData();
|
||||
const QMetaObject *mo = &QTreeView::staticMetaObject;
|
||||
QBENCHMARK {
|
||||
(void)mo->indexOfProperty(p);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaObject::indexOfMethod_data()
|
||||
{
|
||||
QTest::addColumn<QByteArray>("method");
|
||||
const QMetaObject *mo = &QTreeView::staticMetaObject;
|
||||
for (int i = 0; i < mo->methodCount(); ++i) {
|
||||
QMetaMethod method = mo->method(i);
|
||||
QByteArray sig = method.methodSignature();
|
||||
QTest::newRow(sig) << sig;
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaObject::indexOfMethod()
|
||||
{
|
||||
QFETCH(QByteArray, method);
|
||||
const char *p = method.constData();
|
||||
const QMetaObject *mo = &QTreeView::staticMetaObject;
|
||||
QBENCHMARK {
|
||||
(void)mo->indexOfMethod(p);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaObject::indexOfSignal_data()
|
||||
{
|
||||
QTest::addColumn<QByteArray>("signal");
|
||||
const QMetaObject *mo = &QTreeView::staticMetaObject;
|
||||
for (int i = 0; i < mo->methodCount(); ++i) {
|
||||
QMetaMethod method = mo->method(i);
|
||||
if (method.methodType() != QMetaMethod::Signal)
|
||||
continue;
|
||||
QByteArray sig = method.methodSignature();
|
||||
QTest::newRow(sig) << sig;
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaObject::indexOfSignal()
|
||||
{
|
||||
QFETCH(QByteArray, signal);
|
||||
const char *p = signal.constData();
|
||||
const QMetaObject *mo = &QTreeView::staticMetaObject;
|
||||
QBENCHMARK {
|
||||
(void)mo->indexOfSignal(p);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaObject::indexOfSlot_data()
|
||||
{
|
||||
QTest::addColumn<QByteArray>("slot");
|
||||
const QMetaObject *mo = &QTreeView::staticMetaObject;
|
||||
for (int i = 0; i < mo->methodCount(); ++i) {
|
||||
QMetaMethod method = mo->method(i);
|
||||
if (method.methodType() != QMetaMethod::Slot)
|
||||
continue;
|
||||
QByteArray sig = method.methodSignature();
|
||||
QTest::newRow(sig) << sig;
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaObject::indexOfSlot()
|
||||
{
|
||||
QFETCH(QByteArray, slot);
|
||||
const char *p = slot.constData();
|
||||
const QMetaObject *mo = &QTreeView::staticMetaObject;
|
||||
QBENCHMARK {
|
||||
(void)mo->indexOfSlot(p);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaObject::unconnected_data()
|
||||
{
|
||||
QTest::addColumn<int>("signal_index");
|
||||
QTest::newRow("signal--9") << 9;
|
||||
QTest::newRow("signal--32") << 32;
|
||||
QTest::newRow("signal--33") << 33;
|
||||
QTest::newRow("signal--64") << 64;
|
||||
QTest::newRow("signal--65") << 65;
|
||||
QTest::newRow("signal--70") << 70;
|
||||
}
|
||||
|
||||
void tst_QMetaObject::unconnected()
|
||||
{
|
||||
LotsOfSignals *obj = new LotsOfSignals;
|
||||
QFETCH(int, signal_index);
|
||||
// 74: 70 signals in LotsOfSignals, 2 signals, 1 slot + 1 invokable in QObject
|
||||
QCOMPARE(obj->metaObject()->methodCount(), 74);
|
||||
void *v;
|
||||
QBENCHMARK {
|
||||
// Add two because QObject has one slot and one invokable
|
||||
QMetaObject::metacall(obj, QMetaObject::InvokeMetaMethod, signal_index + 2, &v);
|
||||
}
|
||||
delete obj;
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QMetaObject)
|
||||
|
||||
#include "tst_bench_qmetaobject.moc"
|
13
tests/benchmarks/corelib/kernel/qmetatype/CMakeLists.txt
Normal file
13
tests/benchmarks/corelib/kernel/qmetatype/CMakeLists.txt
Normal file
@ -0,0 +1,13 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_bench_qmetatype Binary:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_benchmark(tst_bench_qmetatype
|
||||
SOURCES
|
||||
tst_bench_qmetatype.cpp
|
||||
LIBRARIES
|
||||
Qt::Test
|
||||
)
|
@ -0,0 +1,299 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <qtest.h>
|
||||
#include <QtCore/qmetatype.h>
|
||||
|
||||
class tst_QMetaType : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
tst_QMetaType();
|
||||
virtual ~tst_QMetaType();
|
||||
|
||||
private slots:
|
||||
void typeBuiltin_data();
|
||||
void typeBuiltin();
|
||||
void typeBuiltin_QByteArray_data();
|
||||
void typeBuiltin_QByteArray();
|
||||
void typeBuiltinNotNormalized_data();
|
||||
void typeBuiltinNotNormalized();
|
||||
void typeCustom();
|
||||
void typeCustomNotNormalized();
|
||||
void typeNotRegistered();
|
||||
void typeNotRegisteredNotNormalized();
|
||||
|
||||
void typeNameBuiltin_data();
|
||||
void typeNameBuiltin();
|
||||
void typeNameCustom();
|
||||
void typeNameNotRegistered();
|
||||
|
||||
void isRegisteredBuiltin_data();
|
||||
void isRegisteredBuiltin();
|
||||
void isRegisteredCustom();
|
||||
void isRegisteredNotRegistered();
|
||||
|
||||
void constructInPlace_data();
|
||||
void constructInPlace();
|
||||
void constructInPlaceCopy_data();
|
||||
void constructInPlaceCopy();
|
||||
void constructInPlaceCopyStaticLess_data();
|
||||
void constructInPlaceCopyStaticLess();
|
||||
};
|
||||
|
||||
tst_QMetaType::tst_QMetaType()
|
||||
{
|
||||
}
|
||||
|
||||
tst_QMetaType::~tst_QMetaType()
|
||||
{
|
||||
}
|
||||
|
||||
struct BigClass
|
||||
{
|
||||
double n,i,e,r,o,b;
|
||||
};
|
||||
Q_DECLARE_METATYPE(BigClass);
|
||||
|
||||
void tst_QMetaType::typeBuiltin_data()
|
||||
{
|
||||
QTest::addColumn<QByteArray>("typeName");
|
||||
for (int i = 0; i < QMetaType::User; ++i) {
|
||||
if (QMetaType metaType(i); metaType.isValid())
|
||||
QTest::newRow(metaType.name()) << QByteArray(metaType.name());
|
||||
}
|
||||
}
|
||||
|
||||
// QMetaType::type(const char *)
|
||||
void tst_QMetaType::typeBuiltin()
|
||||
{
|
||||
QFETCH(QByteArray, typeName);
|
||||
const char *nm = typeName.constData();
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < 100000; ++i)
|
||||
QMetaType::fromName(nm);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaType::typeBuiltin_QByteArray_data()
|
||||
{
|
||||
typeBuiltin_data();
|
||||
}
|
||||
|
||||
// QMetaType::type(QByteArray)
|
||||
void tst_QMetaType::typeBuiltin_QByteArray()
|
||||
{
|
||||
QFETCH(QByteArray, typeName);
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < 100000; ++i)
|
||||
QMetaType::fromName(typeName);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaType::typeBuiltinNotNormalized_data()
|
||||
{
|
||||
QTest::addColumn<QByteArray>("typeName");
|
||||
for (int i = 0; i < QMetaType::User; ++i) {
|
||||
if (QMetaType metaType(i); metaType.isValid())
|
||||
QTest::newRow(metaType.name()) << QByteArray(metaType.name()).append(" ");
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaType::typeBuiltinNotNormalized()
|
||||
{
|
||||
QFETCH(QByteArray, typeName);
|
||||
const char *nm = typeName.constData();
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < 10000; ++i)
|
||||
QMetaType::fromName(nm);
|
||||
}
|
||||
}
|
||||
|
||||
struct Foo { int i; };
|
||||
|
||||
void tst_QMetaType::typeCustom()
|
||||
{
|
||||
qRegisterMetaType<Foo>("Foo");
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < 10000; ++i)
|
||||
QMetaType::fromName("Foo");
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaType::typeCustomNotNormalized()
|
||||
{
|
||||
qRegisterMetaType<Foo>("Foo");
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < 10000; ++i)
|
||||
QMetaType::fromName("Foo ");
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaType::typeNotRegistered()
|
||||
{
|
||||
Q_ASSERT(!QMetaType::fromName("Bar").isValid());
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < 10000; ++i)
|
||||
QMetaType::fromName("Bar");
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaType::typeNotRegisteredNotNormalized()
|
||||
{
|
||||
Q_ASSERT(!QMetaType::fromName("Bar").isValid());
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < 10000; ++i)
|
||||
QMetaType::fromName("Bar ");
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaType::typeNameBuiltin_data()
|
||||
{
|
||||
QTest::addColumn<int>("type");
|
||||
for (int i = 0; i < QMetaType::User; ++i) {
|
||||
if (QMetaType metaType(i); metaType.isValid())
|
||||
QTest::newRow(metaType.name()) << i;
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaType::typeNameBuiltin()
|
||||
{
|
||||
QFETCH(int, type);
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < 500000; ++i)
|
||||
QMetaType(type).name();
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaType::typeNameCustom()
|
||||
{
|
||||
int type = qRegisterMetaType<Foo>("Foo");
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < 100000; ++i)
|
||||
QMetaType(type).name();
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaType::typeNameNotRegistered()
|
||||
{
|
||||
// We don't care much about this case, but test it anyway.
|
||||
Q_ASSERT(QMetaType(-1).name() == nullptr);
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < 500000; ++i)
|
||||
QMetaType(-1).name();
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaType::isRegisteredBuiltin_data()
|
||||
{
|
||||
typeNameBuiltin_data();
|
||||
}
|
||||
|
||||
void tst_QMetaType::isRegisteredBuiltin()
|
||||
{
|
||||
QFETCH(int, type);
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < 500000; ++i)
|
||||
QMetaType::isRegistered(type);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaType::isRegisteredCustom()
|
||||
{
|
||||
int type = qRegisterMetaType<Foo>("Foo");
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < 100000; ++i)
|
||||
QMetaType::isRegistered(type);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaType::isRegisteredNotRegistered()
|
||||
{
|
||||
Q_ASSERT(QMetaType(-1).name() == nullptr);
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < 100000; ++i)
|
||||
QMetaType::isRegistered(-1);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMetaType::constructInPlace_data()
|
||||
{
|
||||
QTest::addColumn<int>("typeId");
|
||||
for (int i = QMetaType::FirstCoreType; i <= QMetaType::LastCoreType; ++i) {
|
||||
auto name = QMetaType(i).name();
|
||||
if (name && i != QMetaType::Void)
|
||||
QTest::newRow(name) << i;
|
||||
}
|
||||
|
||||
QTest::newRow("custom") << qMetaTypeId<BigClass>();
|
||||
// GUI types are tested in tst_QGuiMetaType.
|
||||
}
|
||||
|
||||
void tst_QMetaType::constructInPlace()
|
||||
{
|
||||
QFETCH(int, typeId);
|
||||
const QMetaType metaType(typeId);
|
||||
size_t size = metaType.sizeOf();
|
||||
void *storage = qMallocAligned(size, 2 * sizeof(qlonglong));
|
||||
QCOMPARE(metaType.construct(storage, /*copy=*/0), storage);
|
||||
metaType.destruct(storage);
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < 100000; ++i) {
|
||||
metaType.construct(storage, /*copy=*/0);
|
||||
metaType.destruct(storage);
|
||||
}
|
||||
}
|
||||
qFreeAligned(storage);
|
||||
}
|
||||
|
||||
void tst_QMetaType::constructInPlaceCopy_data()
|
||||
{
|
||||
constructInPlace_data();
|
||||
}
|
||||
|
||||
void tst_QMetaType::constructInPlaceCopy()
|
||||
{
|
||||
QFETCH(int, typeId);
|
||||
const QMetaType metaType(typeId);
|
||||
size_t size = metaType.sizeOf();
|
||||
void *storage = qMallocAligned(size, 2 * sizeof(qlonglong));
|
||||
void *other = metaType.create();
|
||||
QCOMPARE(metaType.construct(storage, other), storage);
|
||||
metaType.destruct(storage);
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < 100000; ++i) {
|
||||
metaType.construct(storage, other);
|
||||
metaType.destruct(storage);
|
||||
}
|
||||
}
|
||||
metaType.destroy(other);
|
||||
qFreeAligned(storage);
|
||||
}
|
||||
|
||||
void tst_QMetaType::constructInPlaceCopyStaticLess_data()
|
||||
{
|
||||
constructInPlaceCopy_data();
|
||||
}
|
||||
|
||||
void tst_QMetaType::constructInPlaceCopyStaticLess()
|
||||
{
|
||||
QFETCH(int, typeId);
|
||||
const QMetaType metaType(typeId);
|
||||
size_t size = metaType.sizeOf();
|
||||
void *storage = qMallocAligned(size, 2 * sizeof(qlonglong));
|
||||
void *other = metaType.create();
|
||||
QCOMPARE(metaType.construct(storage, other), storage);
|
||||
metaType.destruct(storage);
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < 100000; ++i) {
|
||||
metaType.construct(storage, other);
|
||||
metaType.destruct(storage);
|
||||
}
|
||||
}
|
||||
metaType.destroy(other);
|
||||
qFreeAligned(storage);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QMetaType)
|
||||
#include "tst_bench_qmetatype.moc"
|
16
tests/benchmarks/corelib/kernel/qobject/CMakeLists.txt
Normal file
16
tests/benchmarks/corelib/kernel/qobject/CMakeLists.txt
Normal file
@ -0,0 +1,16 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_bench_qobject Binary:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_benchmark(tst_bench_qobject
|
||||
SOURCES
|
||||
tst_bench_qobject.cpp
|
||||
object.cpp object.h
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::Test
|
||||
Qt::Widgets
|
||||
)
|
30
tests/benchmarks/corelib/kernel/qobject/object.cpp
Normal file
30
tests/benchmarks/corelib/kernel/qobject/object.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
#include "object.h"
|
||||
|
||||
void Object::emitSignal0()
|
||||
{ emit signal0(); }
|
||||
void Object::emitSignal1()
|
||||
{ emit signal1(); }
|
||||
|
||||
|
||||
void Object::slot0()
|
||||
{ }
|
||||
void Object::slot1()
|
||||
{ }
|
||||
void Object::slot2()
|
||||
{ }
|
||||
void Object::slot3()
|
||||
{ }
|
||||
void Object::slot4()
|
||||
{ }
|
||||
void Object::slot5()
|
||||
{ }
|
||||
void Object::slot6()
|
||||
{ }
|
||||
void Object::slot7()
|
||||
{ }
|
||||
void Object::slot8()
|
||||
{ }
|
||||
void Object::slot9()
|
||||
{ }
|
38
tests/benchmarks/corelib/kernel/qobject/object.h
Normal file
38
tests/benchmarks/corelib/kernel/qobject/object.h
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
#ifndef OBJECT_H
|
||||
#define OBJECT_H
|
||||
|
||||
#include <qobject.h>
|
||||
|
||||
class Object : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
void emitSignal0();
|
||||
void emitSignal1();
|
||||
signals:
|
||||
void signal0();
|
||||
void signal1();
|
||||
void signal2();
|
||||
void signal3();
|
||||
void signal4();
|
||||
void signal5();
|
||||
void signal6();
|
||||
void signal7();
|
||||
void signal8();
|
||||
void signal9();
|
||||
public slots:
|
||||
void slot0();
|
||||
void slot1();
|
||||
void slot2();
|
||||
void slot3();
|
||||
void slot4();
|
||||
void slot5();
|
||||
void slot6();
|
||||
void slot7();
|
||||
void slot8();
|
||||
void slot9();
|
||||
};
|
||||
|
||||
#endif // OBJECT_H
|
285
tests/benchmarks/corelib/kernel/qobject/tst_bench_qobject.cpp
Normal file
285
tests/benchmarks/corelib/kernel/qobject/tst_bench_qobject.cpp
Normal file
@ -0,0 +1,285 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
#include <QtCore>
|
||||
#include <QtWidgets/QTreeView>
|
||||
#include <qtest.h>
|
||||
#include "object.h"
|
||||
#include <qcoreapplication.h>
|
||||
#include <qdatetime.h>
|
||||
|
||||
enum {
|
||||
CreationDeletionBenckmarkConstant = 34567,
|
||||
SignalsAndSlotsBenchmarkConstant = 456789
|
||||
};
|
||||
|
||||
class tst_QObject : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void signal_slot_benchmark();
|
||||
void signal_slot_benchmark_data();
|
||||
void signal_many_receivers();
|
||||
void signal_many_receivers_data();
|
||||
void qproperty_benchmark_data();
|
||||
void qproperty_benchmark();
|
||||
void dynamic_property_benchmark();
|
||||
void connect_disconnect_benchmark_data();
|
||||
void connect_disconnect_benchmark();
|
||||
void receiver_destroyed_benchmark();
|
||||
|
||||
void stdAllocator();
|
||||
};
|
||||
|
||||
class QObjectUsingStandardAllocator : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QObjectUsingStandardAllocator()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
inline void allocator()
|
||||
{
|
||||
// We need to allocate certain amount of objects otherwise the new implementation
|
||||
// may re-use the previous allocation, hiding the somehow high cost of allocation. It
|
||||
// also helps us to reduce the noise ratio, which is high for memory allocation.
|
||||
//
|
||||
// The check depends on memory allocation performance, which is quite non-deterministic.
|
||||
// When a new memory is requested, the new operator, depending on implementation, is trying
|
||||
// to re-use existing, already allocated for the process memory. If there is not enough, it
|
||||
// asks OS to give more. Of course the first case is faster then the second. In the same
|
||||
// time, from an application perspective the first is also more likely.
|
||||
//
|
||||
// As a result, depending on which use-case one wants to test, it may be recommended to run this
|
||||
// test in separation from others, to "force" expensive code path in the memory allocation.
|
||||
//
|
||||
// The time based results are heavily affected by background noise. One really needs to
|
||||
// prepare OS (no other tasks, CPU and RAM reservations) to run this test, or use
|
||||
// instruction counting which seems to be less fragile.
|
||||
|
||||
const int count = 256 * 1024;
|
||||
|
||||
QScopedPointer<T> objects[count];
|
||||
QBENCHMARK_ONCE {
|
||||
for (int i = 0; i < count; ++i)
|
||||
objects[i].reset(new T);
|
||||
for (int i = 0; i < count; ++i)
|
||||
objects[i].reset();
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QObject::stdAllocator()
|
||||
{
|
||||
allocator<QObjectUsingStandardAllocator>();
|
||||
}
|
||||
|
||||
struct Functor {
|
||||
void operator()(){}
|
||||
};
|
||||
|
||||
void tst_QObject::signal_slot_benchmark_data()
|
||||
{
|
||||
QTest::addColumn<int>("type");
|
||||
QTest::newRow("simple function") << 0;
|
||||
QTest::newRow("single signal/slot") << 1;
|
||||
QTest::newRow("multi signal/slot") << 2;
|
||||
QTest::newRow("unconnected signal") << 3;
|
||||
QTest::newRow("single signal/ptr") << 4;
|
||||
QTest::newRow("functor") << 5;
|
||||
}
|
||||
|
||||
void tst_QObject::signal_slot_benchmark()
|
||||
{
|
||||
QFETCH(int, type);
|
||||
|
||||
Object singleObject;
|
||||
Object multiObject;
|
||||
Functor functor;
|
||||
singleObject.setObjectName("single");
|
||||
multiObject.setObjectName("multi");
|
||||
|
||||
if (type == 5) {
|
||||
QObject::connect(&singleObject, &Object::signal0, functor);
|
||||
} else if (type == 4) {
|
||||
QObject::connect(&singleObject, &Object::signal0, &singleObject, &Object::slot0);
|
||||
} else {
|
||||
singleObject.connect(&singleObject, SIGNAL(signal0()), SLOT(slot0()));
|
||||
}
|
||||
|
||||
multiObject.connect(&multiObject, SIGNAL(signal0()), SLOT(slot0()));
|
||||
// multiObject.connect(&multiObject, SIGNAL(signal0()), SLOT(signal1()));
|
||||
multiObject.connect(&multiObject, SIGNAL(signal1()), SLOT(slot1()));
|
||||
// multiObject.connect(&multiObject, SIGNAL(signal0()), SLOT(signal2()));
|
||||
multiObject.connect(&multiObject, SIGNAL(signal2()), SLOT(slot2()));
|
||||
// multiObject.connect(&multiObject, SIGNAL(signal0()), SLOT(signal3()));
|
||||
multiObject.connect(&multiObject, SIGNAL(signal3()), SLOT(slot3()));
|
||||
// multiObject.connect(&multiObject, SIGNAL(signal0()), SLOT(signal4()));
|
||||
multiObject.connect(&multiObject, SIGNAL(signal4()), SLOT(slot4()));
|
||||
// multiObject.connect(&multiObject, SIGNAL(signal0()), SLOT(signal5()));
|
||||
multiObject.connect(&multiObject, SIGNAL(signal5()), SLOT(slot5()));
|
||||
// multiObject.connect(&multiObject, SIGNAL(signal0()), SLOT(signal6()));
|
||||
multiObject.connect(&multiObject, SIGNAL(signal6()), SLOT(slot6()));
|
||||
// multiObject.connect(&multiObject, SIGNAL(signal0()), SLOT(signal7()));
|
||||
multiObject.connect(&multiObject, SIGNAL(signal7()), SLOT(slot7()));
|
||||
// multiObject.connect(&multiObject, SIGNAL(signal0()), SLOT(signal8()));
|
||||
multiObject.connect(&multiObject, SIGNAL(signal8()), SLOT(slot8()));
|
||||
// multiObject.connect(&multiObject, SIGNAL(signal0()), SLOT(signal9()));
|
||||
multiObject.connect(&multiObject, SIGNAL(signal9()), SLOT(slot9()));
|
||||
|
||||
if (type == 0) {
|
||||
QBENCHMARK {
|
||||
singleObject.slot0();
|
||||
}
|
||||
} else if (type == 1) {
|
||||
QBENCHMARK {
|
||||
singleObject.emitSignal0();
|
||||
}
|
||||
} else if (type == 2) {
|
||||
QBENCHMARK {
|
||||
multiObject.emitSignal0();
|
||||
}
|
||||
} else if (type == 3) {
|
||||
QBENCHMARK {
|
||||
singleObject.emitSignal1();
|
||||
}
|
||||
} else if (type == 4 || type == 5) {
|
||||
QBENCHMARK {
|
||||
singleObject.emitSignal0();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QObject::signal_many_receivers_data()
|
||||
{
|
||||
QTest::addColumn<int>("receiverCount");
|
||||
QTest::newRow("100 receivers") << 100;
|
||||
QTest::newRow("1 000 receivers") << 1000;
|
||||
QTest::newRow("10 000 receivers") << 10000;
|
||||
}
|
||||
|
||||
void tst_QObject::signal_many_receivers()
|
||||
{
|
||||
QFETCH(int, receiverCount);
|
||||
Object sender;
|
||||
std::vector<Object> receivers(receiverCount);
|
||||
|
||||
for (Object &receiver : receivers)
|
||||
QObject::connect(&sender, &Object::signal0, &receiver, &Object::slot0);
|
||||
|
||||
QBENCHMARK {
|
||||
sender.emitSignal0();
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QObject::qproperty_benchmark_data()
|
||||
{
|
||||
QTest::addColumn<QByteArray>("name");
|
||||
const QMetaObject *mo = &QTreeView::staticMetaObject;
|
||||
for (int i = 0; i < mo->propertyCount(); ++i) {
|
||||
QMetaProperty prop = mo->property(i);
|
||||
if (prop.isWritable())
|
||||
QTest::newRow(prop.name()) << QByteArray(prop.name());
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QObject::qproperty_benchmark()
|
||||
{
|
||||
QFETCH(QByteArray, name);
|
||||
const char *p = name.constData();
|
||||
QTreeView obj;
|
||||
QVariant v = obj.property(p);
|
||||
QBENCHMARK {
|
||||
obj.setProperty(p, v);
|
||||
(void)obj.property(p);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QObject::dynamic_property_benchmark()
|
||||
{
|
||||
QTreeView obj;
|
||||
QBENCHMARK {
|
||||
obj.setProperty("myProperty", 123);
|
||||
(void)obj.property("myProperty");
|
||||
obj.setProperty("myOtherProperty", 123);
|
||||
(void)obj.property("myOtherProperty");
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QObject::connect_disconnect_benchmark_data()
|
||||
{
|
||||
QTest::addColumn<int>("type");
|
||||
QTest::newRow("normalized signature") << 0;
|
||||
QTest::newRow("unormalized signature") << 1;
|
||||
QTest::newRow("function pointer") << 2;
|
||||
QTest::newRow("normalized signature/handle") << 3;
|
||||
QTest::newRow("unormalized signature/handle") << 4;
|
||||
QTest::newRow("function pointer/handle") << 5;
|
||||
QTest::newRow("functor/handle") << 6;}
|
||||
|
||||
void tst_QObject::connect_disconnect_benchmark()
|
||||
{
|
||||
QFETCH(int, type);
|
||||
switch (type) {
|
||||
case 0: {
|
||||
QTreeView obj;
|
||||
QBENCHMARK {
|
||||
QObject::connect (&obj, SIGNAL(viewportEntered()), &obj, SLOT(expandAll()));
|
||||
QObject::disconnect(&obj, SIGNAL(viewportEntered()), &obj, SLOT(expandAll()));
|
||||
}
|
||||
} break;
|
||||
case 1: {
|
||||
QTreeView obj;
|
||||
QBENCHMARK {
|
||||
QObject::connect (&obj, SIGNAL(viewportEntered( )), &obj, SLOT(expandAll( ))); // sic: non-normalised
|
||||
QObject::disconnect(&obj, SIGNAL(viewportEntered( )), &obj, SLOT(expandAll( ))); // sic: non-normalised
|
||||
}
|
||||
} break;
|
||||
case 2: {
|
||||
QTreeView obj;
|
||||
QBENCHMARK {
|
||||
QObject::connect (&obj, &QAbstractItemView::viewportEntered, &obj, &QTreeView::expandAll);
|
||||
QObject::disconnect(&obj, &QAbstractItemView::viewportEntered, &obj, &QTreeView::expandAll);
|
||||
}
|
||||
} break;
|
||||
case 3: {
|
||||
QTreeView obj;
|
||||
QBENCHMARK {
|
||||
QObject::disconnect(QObject::connect(&obj, SIGNAL(viewportEntered()), &obj, SLOT(expandAll())));
|
||||
}
|
||||
} break;
|
||||
case 4: {
|
||||
QTreeView obj;
|
||||
QBENCHMARK {
|
||||
QObject::disconnect(QObject::connect(&obj, SIGNAL(viewportEntered( )), &obj, SLOT(expandAll( )))); // sic: non-normalised
|
||||
}
|
||||
} break;
|
||||
case 5: {
|
||||
QTreeView obj;
|
||||
QBENCHMARK {
|
||||
QObject::disconnect(QObject::connect(&obj, &QAbstractItemView::viewportEntered, &obj, &QTreeView::expandAll));
|
||||
}
|
||||
} break;
|
||||
case 6: {
|
||||
QTreeView obj;
|
||||
Functor functor;
|
||||
QBENCHMARK {
|
||||
QObject::disconnect(QObject::connect(&obj, &QAbstractItemView::viewportEntered, functor));
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QObject::receiver_destroyed_benchmark()
|
||||
{
|
||||
Object sender;
|
||||
QBENCHMARK {
|
||||
Object receiver;
|
||||
QObject::connect(&sender, &Object::signal0, &receiver, &Object::slot0);
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QObject)
|
||||
|
||||
#include "tst_bench_qobject.moc"
|
11
tests/benchmarks/corelib/kernel/qproperty/CMakeLists.txt
Normal file
11
tests/benchmarks/corelib/kernel/qproperty/CMakeLists.txt
Normal file
@ -0,0 +1,11 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
qt_internal_add_benchmark(tst_bench_qproperty
|
||||
SOURCES
|
||||
tst_bench_qproperty.cpp
|
||||
propertytester.h
|
||||
LIBRARIES
|
||||
Qt::Core
|
||||
Qt::Test
|
||||
)
|
58
tests/benchmarks/corelib/kernel/qproperty/propertytester.h
Normal file
58
tests/benchmarks/corelib/kernel/qproperty/propertytester.h
Normal file
@ -0,0 +1,58 @@
|
||||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#ifndef PROPERTYTESTER_H
|
||||
#define PROPERTYTESTER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QProperty>
|
||||
|
||||
class PropertyTester : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
signals:
|
||||
void xOldChanged();
|
||||
void yOldChanged();
|
||||
void xNotifiedChanged();
|
||||
void yNotifiedChanged();
|
||||
|
||||
public:
|
||||
PropertyTester() = default;
|
||||
Q_PROPERTY(int xOld READ xOld WRITE setXOld NOTIFY xOldChanged)
|
||||
Q_PROPERTY(int yOld READ yOld WRITE setYOld NOTIFY yOldChanged)
|
||||
Q_PROPERTY(int x MEMBER x BINDABLE xBindable)
|
||||
Q_PROPERTY(int y MEMBER y BINDABLE yBindable)
|
||||
Q_PROPERTY(int xNotified MEMBER xNotified NOTIFY xNotifiedChanged BINDABLE xNotifiedBindable)
|
||||
Q_PROPERTY(int yNotified MEMBER yNotified NOTIFY yNotifiedChanged BINDABLE yNotifiedBindable)
|
||||
void setXOld(int i) {
|
||||
if (m_xOld != i) {
|
||||
m_xOld = i;
|
||||
emit xOldChanged();
|
||||
}
|
||||
}
|
||||
void setYOld(int i) {
|
||||
if (m_yOld != i) {
|
||||
m_yOld = i;
|
||||
emit yOldChanged();
|
||||
}
|
||||
}
|
||||
int xOld() { return m_xOld; }
|
||||
int yOld() { return m_yOld; }
|
||||
QProperty<int> x;
|
||||
QProperty<int> y;
|
||||
|
||||
QBindable<int> xBindable() { return QBindable<int>(&x); }
|
||||
QBindable<int> yBindable() { return QBindable<int>(&y); }
|
||||
|
||||
Q_OBJECT_BINDABLE_PROPERTY(PropertyTester, int, xNotified, &PropertyTester::xNotifiedChanged)
|
||||
Q_OBJECT_BINDABLE_PROPERTY(PropertyTester, int, yNotified, &PropertyTester::yNotifiedChanged)
|
||||
|
||||
QBindable<int> xNotifiedBindable() { return QBindable<int>(&xNotified); }
|
||||
QBindable<int> yNotifiedBindable() { return QBindable<int>(&yNotified); }
|
||||
|
||||
private:
|
||||
int m_xOld = 0;
|
||||
int m_yOld = 0;
|
||||
};
|
||||
|
||||
#endif // PROPERTYTESTER_H
|
@ -0,0 +1,207 @@
|
||||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <QScopedPointer>
|
||||
#include <QProperty>
|
||||
|
||||
#include <qtest.h>
|
||||
|
||||
#include "propertytester.h"
|
||||
|
||||
class tst_QProperty : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void cppOldBinding();
|
||||
void cppOldBindingReadOnce();
|
||||
void cppOldBindingDirect();
|
||||
void cppOldBindingDirectReadOnce();
|
||||
|
||||
void cppNewBinding();
|
||||
void cppNewBindingReadOnce();
|
||||
void cppNewBindingDirect();
|
||||
void cppNewBindingDirectReadOnce();
|
||||
|
||||
void cppNotifying();
|
||||
void cppNotifyingReadOnce();
|
||||
void cppNotifyingDirect();
|
||||
void cppNotifyingDirectReadOnce();
|
||||
};
|
||||
|
||||
void tst_QProperty::cppOldBinding()
|
||||
{
|
||||
QScopedPointer<PropertyTester> tester {new PropertyTester};
|
||||
auto connection = connect(tester.data(), &PropertyTester::xOldChanged,
|
||||
tester.data(), [&]() { tester->setYOld(tester->xOld()); });
|
||||
|
||||
QCOMPARE(tester->property("yOld").toInt(), 0);
|
||||
int i = 0;
|
||||
QBENCHMARK {
|
||||
tester->setProperty("xOld", ++i);
|
||||
if (tester->property("yOld").toInt() != i)
|
||||
QFAIL("boo");
|
||||
}
|
||||
|
||||
QObject::disconnect(connection);
|
||||
}
|
||||
|
||||
void tst_QProperty::cppOldBindingDirect()
|
||||
{
|
||||
QScopedPointer<PropertyTester> tester {new PropertyTester};
|
||||
auto connection = connect(tester.data(), &PropertyTester::xOldChanged,
|
||||
tester.data(), [&]() { tester->setYOld(tester->xOld()); });
|
||||
|
||||
QCOMPARE(tester->yOld(), 0);
|
||||
int i = 0;
|
||||
QBENCHMARK {
|
||||
tester->setXOld(++i);
|
||||
if (tester->yOld() != i)
|
||||
QFAIL("boo");
|
||||
}
|
||||
|
||||
QObject::disconnect(connection);
|
||||
}
|
||||
|
||||
void tst_QProperty::cppOldBindingReadOnce()
|
||||
{
|
||||
QScopedPointer<PropertyTester> tester {new PropertyTester};
|
||||
auto connection = connect(tester.data(), &PropertyTester::xOldChanged,
|
||||
tester.data(), [&]() { tester->setYOld(tester->xOld()); });
|
||||
|
||||
QCOMPARE(tester->property("yOld").toInt(), 0);
|
||||
int i = 0;
|
||||
QBENCHMARK {
|
||||
tester->setProperty("xOld", ++i);
|
||||
}
|
||||
|
||||
QCOMPARE(tester->property("yOld").toInt(), i);
|
||||
QObject::disconnect(connection);
|
||||
}
|
||||
|
||||
void tst_QProperty::cppOldBindingDirectReadOnce()
|
||||
{
|
||||
QScopedPointer<PropertyTester> tester {new PropertyTester};
|
||||
auto connection = connect(tester.data(), &PropertyTester::xOldChanged,
|
||||
tester.data(), [&]() { tester->setYOld(tester->xOld()); });
|
||||
|
||||
QCOMPARE(tester->yOld(), 0);
|
||||
int i = 0;
|
||||
QBENCHMARK {
|
||||
tester->setXOld(++i);
|
||||
}
|
||||
|
||||
QCOMPARE(tester->yOld(), i);
|
||||
QObject::disconnect(connection);
|
||||
}
|
||||
|
||||
void tst_QProperty::cppNewBinding()
|
||||
{
|
||||
QScopedPointer<PropertyTester> tester {new PropertyTester};
|
||||
tester->y.setBinding([&](){return tester->x.value();});
|
||||
|
||||
QCOMPARE(tester->property("y").toInt(), 0);
|
||||
int i = 0;
|
||||
QBENCHMARK {
|
||||
tester->setProperty("x", ++i);
|
||||
if (tester->property("y").toInt() != i)
|
||||
QFAIL("boo");
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QProperty::cppNewBindingDirect()
|
||||
{
|
||||
QScopedPointer<PropertyTester> tester {new PropertyTester};
|
||||
tester->y.setBinding([&](){return tester->x.value();});
|
||||
QCOMPARE(tester->y.value(), 0);
|
||||
int i = 0;
|
||||
QBENCHMARK {
|
||||
tester->x = ++i;
|
||||
if (tester->y.value() != i)
|
||||
QFAIL("boo");
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QProperty::cppNewBindingReadOnce()
|
||||
{
|
||||
QScopedPointer<PropertyTester> tester {new PropertyTester};
|
||||
tester->y.setBinding([&](){return tester->x.value();});
|
||||
|
||||
QCOMPARE(tester->property("y").toInt(), 0);
|
||||
int i = 0;
|
||||
QBENCHMARK {
|
||||
tester->setProperty("x", ++i);
|
||||
}
|
||||
|
||||
QCOMPARE(tester->property("y").toInt(), i);
|
||||
}
|
||||
|
||||
void tst_QProperty::cppNewBindingDirectReadOnce()
|
||||
{
|
||||
QScopedPointer<PropertyTester> tester {new PropertyTester};
|
||||
tester->y.setBinding([&](){return tester->x.value();});
|
||||
QCOMPARE(tester->y.value(), 0);
|
||||
int i = 0;
|
||||
QBENCHMARK {
|
||||
tester->x = ++i;
|
||||
}
|
||||
|
||||
QCOMPARE(tester->y.value(), i);
|
||||
}
|
||||
|
||||
void tst_QProperty::cppNotifying()
|
||||
{
|
||||
QScopedPointer<PropertyTester> tester {new PropertyTester};
|
||||
tester->yNotified.setBinding([&](){return tester->xNotified.value();});
|
||||
|
||||
QCOMPARE(tester->property("yNotified").toInt(), 0);
|
||||
int i = 0;
|
||||
QBENCHMARK {
|
||||
tester->setProperty("xNotified", ++i);
|
||||
if (tester->property("yNotified").toInt() != i)
|
||||
QFAIL("boo");
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QProperty::cppNotifyingDirect()
|
||||
{
|
||||
QScopedPointer<PropertyTester> tester {new PropertyTester};
|
||||
tester->yNotified.setBinding([&](){return tester->xNotified.value();});
|
||||
QCOMPARE(tester->yNotified.value(), 0);
|
||||
int i = 0;
|
||||
QBENCHMARK {
|
||||
tester->xNotified.setValue(++i);
|
||||
if (tester->yNotified.value() != i)
|
||||
QFAIL("boo");
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QProperty::cppNotifyingReadOnce()
|
||||
{
|
||||
QScopedPointer<PropertyTester> tester {new PropertyTester};
|
||||
tester->yNotified.setBinding([&](){return tester->xNotified.value();});
|
||||
|
||||
QCOMPARE(tester->property("yNotified").toInt(), 0);
|
||||
int i = 0;
|
||||
QBENCHMARK {
|
||||
tester->setProperty("xNotified", ++i);
|
||||
}
|
||||
|
||||
QCOMPARE(tester->property("yNotified").toInt(), i);
|
||||
}
|
||||
|
||||
void tst_QProperty::cppNotifyingDirectReadOnce()
|
||||
{
|
||||
QScopedPointer<PropertyTester> tester {new PropertyTester};
|
||||
tester->yNotified.setBinding([&](){return tester->xNotified.value();});
|
||||
QCOMPARE(tester->yNotified.value(), 0);
|
||||
int i = 0;
|
||||
QBENCHMARK {
|
||||
tester->xNotified.setValue(++i);
|
||||
}
|
||||
|
||||
QCOMPARE(tester->yNotified.value(), i);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QProperty)
|
||||
|
||||
#include "tst_bench_qproperty.moc"
|
@ -0,0 +1,15 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## qtimer_vs_qmetaobject Binary:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_benchmark(qtimer_vs_qmetaobject
|
||||
SOURCES
|
||||
tst_qtimer_vs_qmetaobject.cpp
|
||||
INCLUDE_DIRECTORIES
|
||||
.
|
||||
LIBRARIES
|
||||
Qt::Test
|
||||
)
|
@ -0,0 +1,115 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <QtCore>
|
||||
#include <QTest>
|
||||
#include <QThread>
|
||||
#include <QSignalSpy>
|
||||
|
||||
#define INVOKE_COUNT 10000
|
||||
|
||||
class qtimer_vs_qmetaobject : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void bench();
|
||||
void bench_data();
|
||||
void benchBackgroundThread();
|
||||
void benchBackgroundThread_data() { bench_data(); }
|
||||
};
|
||||
|
||||
class InvokeCounter : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
InvokeCounter() : count(0) { };
|
||||
public slots:
|
||||
void invokeSlot() {
|
||||
count++;
|
||||
if (count == INVOKE_COUNT)
|
||||
emit allInvoked();
|
||||
}
|
||||
signals:
|
||||
void allInvoked();
|
||||
protected:
|
||||
int count;
|
||||
};
|
||||
|
||||
void qtimer_vs_qmetaobject::bench()
|
||||
{
|
||||
QFETCH(int, type);
|
||||
|
||||
std::function<void(InvokeCounter*)> invoke;
|
||||
if (type == 0) {
|
||||
invoke = [](InvokeCounter* invokeCounter) {
|
||||
QTimer::singleShot(0, invokeCounter, SLOT(invokeSlot()));
|
||||
};
|
||||
} else if (type == 1) {
|
||||
invoke = [](InvokeCounter* invokeCounter) {
|
||||
QTimer::singleShot(0, invokeCounter, &InvokeCounter::invokeSlot);
|
||||
};
|
||||
} else if (type == 2) {
|
||||
invoke = [](InvokeCounter* invokeCounter) {
|
||||
QTimer::singleShot(0, invokeCounter, [invokeCounter]() {
|
||||
invokeCounter->invokeSlot();
|
||||
});
|
||||
};
|
||||
} else if (type == 3) {
|
||||
invoke = [](InvokeCounter* invokeCounter) {
|
||||
QTimer::singleShot(0, [invokeCounter]() {
|
||||
invokeCounter->invokeSlot();
|
||||
});
|
||||
};
|
||||
} else if (type == 4) {
|
||||
invoke = [](InvokeCounter* invokeCounter) {
|
||||
QMetaObject::invokeMethod(invokeCounter, "invokeSlot", Qt::QueuedConnection);
|
||||
};
|
||||
} else if (type == 5) {
|
||||
invoke = [](InvokeCounter* invokeCounter) {
|
||||
QMetaObject::invokeMethod(invokeCounter, &InvokeCounter::invokeSlot, Qt::QueuedConnection);
|
||||
};
|
||||
} else if (type == 6) {
|
||||
invoke = [](InvokeCounter* invokeCounter) {
|
||||
QMetaObject::invokeMethod(invokeCounter, [invokeCounter]() {
|
||||
invokeCounter->invokeSlot();
|
||||
}, Qt::QueuedConnection);
|
||||
};
|
||||
} else {
|
||||
QFAIL("unhandled data tag");
|
||||
}
|
||||
|
||||
QBENCHMARK {
|
||||
InvokeCounter invokeCounter;
|
||||
QSignalSpy spy(&invokeCounter, &InvokeCounter::allInvoked);
|
||||
for(int i = 0; i < INVOKE_COUNT; ++i) {
|
||||
invoke(&invokeCounter);
|
||||
}
|
||||
QVERIFY(spy.wait(10000));
|
||||
}
|
||||
}
|
||||
|
||||
void qtimer_vs_qmetaobject::bench_data()
|
||||
{
|
||||
QTest::addColumn<int>("type");
|
||||
QTest::addRow("singleShot_slot") << 0;
|
||||
QTest::addRow("singleShot_pmf") << 1;
|
||||
QTest::addRow("singleShot_functor") << 2;
|
||||
QTest::addRow("singleShot_functor_noctx") << 3;
|
||||
QTest::addRow("invokeMethod_string") << 4;
|
||||
QTest::addRow("invokeMethod_pmf") << 5;
|
||||
QTest::addRow("invokeMethod_functor") << 6;
|
||||
}
|
||||
|
||||
void qtimer_vs_qmetaobject::benchBackgroundThread()
|
||||
{
|
||||
#if !QT_CONFIG(cxx11_future)
|
||||
QSKIP("This test requires QThread::create");
|
||||
#else
|
||||
QScopedPointer<QThread> thread(QThread::create([this]() { bench(); }));
|
||||
thread->start();
|
||||
QVERIFY(thread->wait());
|
||||
#endif
|
||||
}
|
||||
|
||||
QTEST_MAIN(qtimer_vs_qmetaobject)
|
||||
|
||||
#include "tst_qtimer_vs_qmetaobject.moc"
|
21
tests/benchmarks/corelib/kernel/qvariant/CMakeLists.txt
Normal file
21
tests/benchmarks/corelib/kernel/qvariant/CMakeLists.txt
Normal file
@ -0,0 +1,21 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_bench_qvariant Binary:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_benchmark(tst_bench_qvariant
|
||||
SOURCES
|
||||
tst_bench_qvariant.cpp
|
||||
LIBRARIES
|
||||
Qt::Test
|
||||
)
|
||||
|
||||
## Scopes:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_extend_target(tst_bench_qvariant CONDITION TARGET Qt::Gui
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
)
|
356
tests/benchmarks/corelib/kernel/qvariant/tst_bench_qvariant.cpp
Normal file
356
tests/benchmarks/corelib/kernel/qvariant/tst_bench_qvariant.cpp
Normal file
@ -0,0 +1,356 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <QtCore>
|
||||
#ifdef QT_GUI_LIB
|
||||
# include <QtGui/QPixmap>
|
||||
#endif
|
||||
#include <qtest.h>
|
||||
|
||||
#define ITERATION_COUNT 1e5
|
||||
|
||||
class tst_QVariant : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum ABenchmarkEnum {
|
||||
FirstEnumValue,
|
||||
SecondEnumValue,
|
||||
ThirdEnumValue
|
||||
};
|
||||
Q_ENUM(ABenchmarkEnum)
|
||||
|
||||
private slots:
|
||||
void testBound();
|
||||
|
||||
void doubleVariantCreation();
|
||||
void floatVariantCreation();
|
||||
void rectVariantCreation();
|
||||
void stringVariantCreation();
|
||||
#ifdef QT_GUI_LIB
|
||||
void pixmapVariantCreation();
|
||||
#endif
|
||||
void stringListVariantCreation();
|
||||
void bigClassVariantCreation();
|
||||
void smallClassVariantCreation();
|
||||
void enumVariantCreation();
|
||||
|
||||
void doubleVariantSetValue();
|
||||
void floatVariantSetValue();
|
||||
void rectVariantSetValue();
|
||||
void stringVariantSetValue();
|
||||
void stringListVariantSetValue();
|
||||
void bigClassVariantSetValue();
|
||||
void smallClassVariantSetValue();
|
||||
void enumVariantSetValue();
|
||||
|
||||
void doubleVariantAssignment();
|
||||
void floatVariantAssignment();
|
||||
void rectVariantAssignment();
|
||||
void stringVariantAssignment();
|
||||
void stringListVariantAssignment();
|
||||
|
||||
void doubleVariantValue();
|
||||
void floatVariantValue();
|
||||
void rectVariantValue();
|
||||
void stringVariantValue();
|
||||
|
||||
void createCoreType_data();
|
||||
void createCoreType();
|
||||
void createCoreTypeCopy_data();
|
||||
void createCoreTypeCopy();
|
||||
};
|
||||
|
||||
struct BigClass
|
||||
{
|
||||
double n,i,e,r,o,b;
|
||||
};
|
||||
static_assert(sizeof(BigClass) > sizeof(QVariant::Private::MaxInternalSize));
|
||||
QT_BEGIN_NAMESPACE
|
||||
Q_DECLARE_TYPEINFO(BigClass, Q_RELOCATABLE_TYPE);
|
||||
QT_END_NAMESPACE
|
||||
Q_DECLARE_METATYPE(BigClass);
|
||||
|
||||
struct SmallClass
|
||||
{
|
||||
char s;
|
||||
};
|
||||
static_assert(sizeof(SmallClass) <= sizeof(QVariant::Private::MaxInternalSize));
|
||||
QT_BEGIN_NAMESPACE
|
||||
Q_DECLARE_TYPEINFO(SmallClass, Q_RELOCATABLE_TYPE);
|
||||
QT_END_NAMESPACE
|
||||
Q_DECLARE_METATYPE(SmallClass);
|
||||
|
||||
void tst_QVariant::testBound()
|
||||
{
|
||||
qreal d = qreal(.5);
|
||||
QBENCHMARK {
|
||||
for(int i = 0; i < ITERATION_COUNT; ++i) {
|
||||
d = qBound<qreal>(0, d, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void variantCreation(T val)
|
||||
{
|
||||
QBENCHMARK {
|
||||
for(int i = 0; i < ITERATION_COUNT; ++i) {
|
||||
QVariant v(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
void variantCreation<BigClass>(BigClass val)
|
||||
{
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < ITERATION_COUNT; ++i) {
|
||||
QVariant::fromValue(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
void variantCreation<SmallClass>(SmallClass val)
|
||||
{
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < ITERATION_COUNT; ++i) {
|
||||
QVariant::fromValue(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
void variantCreation<tst_QVariant::ABenchmarkEnum>(tst_QVariant::ABenchmarkEnum val)
|
||||
{
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < ITERATION_COUNT; ++i) {
|
||||
QVariant::fromValue(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void tst_QVariant::doubleVariantCreation()
|
||||
{
|
||||
variantCreation<double>(0.0);
|
||||
}
|
||||
|
||||
void tst_QVariant::floatVariantCreation()
|
||||
{
|
||||
variantCreation<float>(0.0f);
|
||||
}
|
||||
|
||||
void tst_QVariant::rectVariantCreation()
|
||||
{
|
||||
variantCreation<QRect>(QRect(1, 2, 3, 4));
|
||||
}
|
||||
|
||||
void tst_QVariant::stringVariantCreation()
|
||||
{
|
||||
variantCreation<QString>(QString());
|
||||
}
|
||||
|
||||
#ifdef QT_GUI_LIB
|
||||
void tst_QVariant::pixmapVariantCreation()
|
||||
{
|
||||
variantCreation<QPixmap>(QPixmap());
|
||||
}
|
||||
#endif
|
||||
|
||||
void tst_QVariant::stringListVariantCreation()
|
||||
{
|
||||
variantCreation<QStringList>(QStringList());
|
||||
}
|
||||
|
||||
void tst_QVariant::bigClassVariantCreation()
|
||||
{
|
||||
variantCreation<BigClass>(BigClass());
|
||||
}
|
||||
|
||||
void tst_QVariant::smallClassVariantCreation()
|
||||
{
|
||||
variantCreation<SmallClass>(SmallClass());
|
||||
}
|
||||
|
||||
void tst_QVariant::enumVariantCreation()
|
||||
{
|
||||
variantCreation<ABenchmarkEnum>(FirstEnumValue);
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
static void variantSetValue(T d)
|
||||
{
|
||||
QVariant v;
|
||||
QBENCHMARK {
|
||||
for(int i = 0; i < ITERATION_COUNT; ++i) {
|
||||
v.setValue(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QVariant::doubleVariantSetValue()
|
||||
{
|
||||
variantSetValue<double>(0.0);
|
||||
}
|
||||
|
||||
void tst_QVariant::floatVariantSetValue()
|
||||
{
|
||||
variantSetValue<float>(0.0f);
|
||||
}
|
||||
|
||||
void tst_QVariant::rectVariantSetValue()
|
||||
{
|
||||
variantSetValue<QRect>(QRect());
|
||||
}
|
||||
|
||||
void tst_QVariant::stringVariantSetValue()
|
||||
{
|
||||
variantSetValue<QString>(QString());
|
||||
}
|
||||
|
||||
void tst_QVariant::stringListVariantSetValue()
|
||||
{
|
||||
variantSetValue<QStringList>(QStringList());
|
||||
}
|
||||
|
||||
void tst_QVariant::bigClassVariantSetValue()
|
||||
{
|
||||
variantSetValue<BigClass>(BigClass());
|
||||
}
|
||||
|
||||
void tst_QVariant::smallClassVariantSetValue()
|
||||
{
|
||||
variantSetValue<SmallClass>(SmallClass());
|
||||
}
|
||||
|
||||
void tst_QVariant::enumVariantSetValue()
|
||||
{
|
||||
variantSetValue<ABenchmarkEnum>(FirstEnumValue);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void variantAssignment(T d)
|
||||
{
|
||||
QVariant v;
|
||||
QBENCHMARK {
|
||||
for(int i = 0; i < ITERATION_COUNT; ++i) {
|
||||
v = d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QVariant::doubleVariantAssignment()
|
||||
{
|
||||
variantAssignment<double>(0.0);
|
||||
}
|
||||
|
||||
void tst_QVariant::floatVariantAssignment()
|
||||
{
|
||||
variantAssignment<float>(0.0f);
|
||||
}
|
||||
|
||||
void tst_QVariant::rectVariantAssignment()
|
||||
{
|
||||
variantAssignment<QRect>(QRect());
|
||||
}
|
||||
|
||||
void tst_QVariant::stringVariantAssignment()
|
||||
{
|
||||
variantAssignment<QString>(QString());
|
||||
}
|
||||
|
||||
void tst_QVariant::stringListVariantAssignment()
|
||||
{
|
||||
variantAssignment<QStringList>(QStringList());
|
||||
}
|
||||
|
||||
void tst_QVariant::doubleVariantValue()
|
||||
{
|
||||
QVariant v(0.0);
|
||||
QBENCHMARK {
|
||||
for(int i = 0; i < ITERATION_COUNT; ++i) {
|
||||
v.toDouble();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QVariant::floatVariantValue()
|
||||
{
|
||||
QVariant v(0.0f);
|
||||
QBENCHMARK {
|
||||
for(int i = 0; i < ITERATION_COUNT; ++i) {
|
||||
v.toFloat();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QVariant::rectVariantValue()
|
||||
{
|
||||
QVariant v(QRect(1,2,3,4));
|
||||
QBENCHMARK {
|
||||
for(int i = 0; i < ITERATION_COUNT; ++i) {
|
||||
v.toRect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QVariant::stringVariantValue()
|
||||
{
|
||||
QVariant v = QString();
|
||||
QBENCHMARK {
|
||||
for(int i = 0; i < ITERATION_COUNT; ++i) {
|
||||
v.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QVariant::createCoreType_data()
|
||||
{
|
||||
QTest::addColumn<int>("typeId");
|
||||
for (int i = QMetaType::FirstCoreType; i <= QMetaType::LastCoreType; ++i) {
|
||||
if (QMetaType metaType(i); metaType.isValid()) // QMetaType(27) does not exist
|
||||
QTest::newRow(metaType.name()) << i;
|
||||
}
|
||||
}
|
||||
|
||||
// Tests how fast a Qt core type can be default-constructed by a
|
||||
// QVariant. The purpose of this benchmark is to measure the overhead
|
||||
// of creating (and destroying) a QVariant compared to creating the
|
||||
// type directly.
|
||||
void tst_QVariant::createCoreType()
|
||||
{
|
||||
QFETCH(int, typeId);
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < ITERATION_COUNT; ++i)
|
||||
QVariant(QMetaType(typeId));
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QVariant::createCoreTypeCopy_data()
|
||||
{
|
||||
createCoreType_data();
|
||||
}
|
||||
|
||||
// Tests how fast a Qt core type can be copy-constructed by a
|
||||
// QVariant. The purpose of this benchmark is to measure the overhead
|
||||
// of creating (and destroying) a QVariant compared to creating the
|
||||
// type directly.
|
||||
void tst_QVariant::createCoreTypeCopy()
|
||||
{
|
||||
QFETCH(int, typeId);
|
||||
QMetaType metaType(typeId);
|
||||
QVariant other(metaType);
|
||||
const void *copy = other.constData();
|
||||
QBENCHMARK {
|
||||
for (int i = 0; i < ITERATION_COUNT; ++i)
|
||||
QVariant(metaType, copy);
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QVariant)
|
||||
|
||||
#include "tst_bench_qvariant.moc"
|
@ -0,0 +1,13 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_bench_qwineventnotifier Binary:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_benchmark(tst_bench_qwineventnotifier
|
||||
SOURCES
|
||||
tst_bench_qwineventnotifier.cpp
|
||||
LIBRARIES
|
||||
Qt::Test
|
||||
)
|
@ -0,0 +1,111 @@
|
||||
// Copyright (C) 2020 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <QTest>
|
||||
#include <QtCore/qglobal.h>
|
||||
#include <QtCore/qwineventnotifier.h>
|
||||
#include <QtCore/qeventloop.h>
|
||||
#include <QtCore/qvector.h>
|
||||
#include <QtCore/qelapsedtimer.h>
|
||||
#include <QtCore/qt_windows.h>
|
||||
|
||||
class tst_QWinEventNotifier : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void waves_data();
|
||||
void waves();
|
||||
};
|
||||
|
||||
class EventsFactory : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit EventsFactory(int waves, int notifiers, int iterations)
|
||||
: numberOfWaves(waves), numberOfNotifiers(notifiers),
|
||||
numberOfIterations(iterations)
|
||||
{
|
||||
events.resize(notifiers);
|
||||
for (int i = 0; i < notifiers; ++i) {
|
||||
events[i] = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
QVERIFY(events[i] != NULL);
|
||||
QWinEventNotifier *notifier = new QWinEventNotifier(events[i], this);
|
||||
Q_CHECK_PTR(notifier);
|
||||
|
||||
connect(notifier, &QWinEventNotifier::activated, [i, this]() {
|
||||
ResetEvent(this->events[i]);
|
||||
if (--this->numberOfIterations == 0)
|
||||
this->eventLoop.quit();
|
||||
else
|
||||
SetEvent(this->events[(i + 1) % this->numberOfNotifiers]);
|
||||
});
|
||||
|
||||
connect(this, &EventsFactory::stop, [notifier]() {
|
||||
notifier->setEnabled(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
virtual ~EventsFactory()
|
||||
{
|
||||
for (auto event : events)
|
||||
CloseHandle(event);
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
Q_ASSERT(numberOfWaves != 0);
|
||||
|
||||
int offset = 0;
|
||||
for (int i = 0; i < numberOfWaves; ++i) {
|
||||
SetEvent(events[offset]);
|
||||
offset += qMax(1, numberOfNotifiers / numberOfWaves);
|
||||
offset %= numberOfNotifiers;
|
||||
}
|
||||
eventLoop.exec();
|
||||
}
|
||||
|
||||
signals:
|
||||
void stop();
|
||||
|
||||
protected:
|
||||
QVector<HANDLE> events;
|
||||
QEventLoop eventLoop;
|
||||
int numberOfWaves;
|
||||
int numberOfNotifiers;
|
||||
int numberOfIterations;
|
||||
};
|
||||
|
||||
void tst_QWinEventNotifier::waves_data()
|
||||
{
|
||||
QTest::addColumn<int>("waves");
|
||||
QTest::addColumn<int>("notifiers");
|
||||
for (int waves : {1, 3, 10}) {
|
||||
for (int notifiers : {10, 100, 1000})
|
||||
QTest::addRow("waves: %d, notifiers: %d", waves, notifiers) << waves << notifiers;
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QWinEventNotifier::waves()
|
||||
{
|
||||
QFETCH(int, waves);
|
||||
QFETCH(int, notifiers);
|
||||
|
||||
const int iterations = 100000;
|
||||
|
||||
EventsFactory factory(waves, notifiers, iterations);
|
||||
|
||||
QElapsedTimer timer;
|
||||
timer.start();
|
||||
|
||||
factory.run();
|
||||
|
||||
qDebug("Elapsed time: %.1f s", timer.elapsed() / 1000.0);
|
||||
|
||||
emit factory.stop();
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QWinEventNotifier)
|
||||
|
||||
#include "tst_bench_qwineventnotifier.moc"
|
Reference in New Issue
Block a user