qt 6.5.1 original

This commit is contained in:
kleuter
2023-10-29 23:33:08 +01:00
parent 71d22ab6b0
commit 85d238dfda
21202 changed files with 5499099 additions and 0 deletions

View 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()

View 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
)

View 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"

View File

@ -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
)

View File

@ -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"

View 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
)

View File

@ -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"

View 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
)

View File

@ -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"

View 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
)

View File

@ -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"

View 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
)

View 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()
{ }

View 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

View 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"

View 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
)

View 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

View File

@ -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"

View File

@ -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
)

View File

@ -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"

View 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
)

View 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"

View File

@ -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
)

View File

@ -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"