1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28#include <QtCore>
29#include <qtest.h>
30#include "object.h"
31#include <qcoreapplication.h>
32#include <qdatetime.h>
33
34enum {
35 CreationDeletionBenckmarkConstant = 34567,
36 SignalsAndSlotsBenchmarkConstant = 456789
37};
38
39class QObjectBenchmark : public QObject
40{
41Q_OBJECT
42private slots:
43 void signal_slot_benchmark();
44 void signal_slot_benchmark_data();
45
46 void connect_disconnect_benchmark_data();
47 void connect_disconnect_benchmark();
48};
49
50struct Functor {
51 void operator()(){}
52};
53
54void QObjectBenchmark::signal_slot_benchmark_data()
55{
56 QTest::addColumn<int>("type");
57 QTest::addColumn<bool>("w");
58 QTest::newRow("simple function") << 0 << false;
59 QTest::newRow("single signal/slot") << 1 << false;
60 QTest::newRow("multi signal/slot") << 2 << false;
61 QTest::newRow("unconnected signal") << 3 << false;
62 QTest::newRow("single signal/ptr") << 4 << false;
63 QTest::newRow("functor") << 5 << false;
64
65 QTest::newRow("w simple function") << 0 << true;
66 QTest::newRow("w single signal/slot") << 1 << true;
67 QTest::newRow("w multi signal/slot") << 2 << true;
68 QTest::newRow("w unconnected signal") << 3 << true;
69 QTest::newRow("w single signal/ptr") << 4 << true;
70 QTest::newRow("w functor") << 5 << true;
71
72}
73
74template<typename Object>
75void signal_slot_benchmark()
76{
77 QFETCH(int, type);
78
79 Object singleObject;
80 Object multiObject;
81 Functor functor;
82 singleObject.setObjectName("single");
83 multiObject.setObjectName("multi");
84
85 if (type == 5) {
86 QObject::connect(&singleObject, &Object::signal0, functor);
87 } else if (type == 4) {
88 QObject::connect(&singleObject, &Object::signal0, &singleObject, &Object::slot0);
89 } else {
90 singleObject.connect(&singleObject, SIGNAL(signal0()), SLOT(slot0()));
91 }
92
93 multiObject.connect(&multiObject, SIGNAL(signal0()), SLOT(slot0()));
94 // multiObject.connect(&multiObject, SIGNAL(signal0()), SLOT(signal1()));
95 multiObject.connect(&multiObject, SIGNAL(signal1()), SLOT(slot1()));
96 // multiObject.connect(&multiObject, SIGNAL(signal0()), SLOT(signal2()));
97 multiObject.connect(&multiObject, SIGNAL(signal2()), SLOT(slot2()));
98 // multiObject.connect(&multiObject, SIGNAL(signal0()), SLOT(signal3()));
99 multiObject.connect(&multiObject, SIGNAL(signal3()), SLOT(slot3()));
100 // multiObject.connect(&multiObject, SIGNAL(signal0()), SLOT(signal4()));
101 multiObject.connect(&multiObject, SIGNAL(signal4()), SLOT(slot4()));
102 // multiObject.connect(&multiObject, SIGNAL(signal0()), SLOT(signal5()));
103 multiObject.connect(&multiObject, SIGNAL(signal5()), SLOT(slot5()));
104 // multiObject.connect(&multiObject, SIGNAL(signal0()), SLOT(signal6()));
105 multiObject.connect(&multiObject, SIGNAL(signal6()), SLOT(slot6()));
106 // multiObject.connect(&multiObject, SIGNAL(signal0()), SLOT(signal7()));
107 multiObject.connect(&multiObject, SIGNAL(signal7()), SLOT(slot7()));
108 // multiObject.connect(&multiObject, SIGNAL(signal0()), SLOT(signal8()));
109 multiObject.connect(&multiObject, SIGNAL(signal8()), SLOT(slot8()));
110 // multiObject.connect(&multiObject, SIGNAL(signal0()), SLOT(signal9()));
111 multiObject.connect(&multiObject, SIGNAL(signal9()), SLOT(slot9()));
112
113 if (type == 0) {
114 QBENCHMARK {
115 singleObject.slot0();
116 }
117 } else if (type == 1) {
118 QBENCHMARK {
119 singleObject.emitSignal0();
120 }
121 } else if (type == 2) {
122 QBENCHMARK {
123 multiObject.emitSignal0();
124 }
125 } else if (type == 3) {
126 QBENCHMARK {
127 singleObject.emitSignal1();
128 }
129 } else if (type == 4 || type == 5) {
130 QBENCHMARK {
131 singleObject.emitSignal0();
132 }
133 }
134}
135
136void QObjectBenchmark::signal_slot_benchmark()
137{
138 QFETCH(bool, w);
139 if (w) ::signal_slot_benchmark<ObjectW>();
140 else ::signal_slot_benchmark<Object>();
141}
142
143void QObjectBenchmark::connect_disconnect_benchmark_data()
144{
145 QTest::addColumn<int>("type");
146 QTest::addColumn<bool>("w");
147
148 QTest::newRow("normalized signature") << 0 << false;
149 QTest::newRow("unormalized signature") << 1 << false;
150 QTest::newRow("function pointer") << 2 << false;
151 QTest::newRow("normalized signature/handle") << 3 << false;
152 QTest::newRow("unormalized signature/handle") << 4 << false;
153 QTest::newRow("function pointer/handle") << 5 << false;
154 QTest::newRow("functor/handle") << 6 << false;
155
156 QTest::newRow("w normalized signature") << 0 << true;
157 QTest::newRow("w unormalized signature") << 1 << true;
158 QTest::newRow("w function pointer") << 2 << true;
159 QTest::newRow("w normalized signature/handle") << 3 << true;
160 QTest::newRow("w unormalized signature/handle") << 4 << true;
161 QTest::newRow("w function pointer/handle") << 5 << true;
162 QTest::newRow("w functor/handle") << 6 << true;
163
164}
165
166template<typename Object>
167void connect_disconnect_benchmark()
168{
169 QFETCH(int, type);
170 switch (type) {
171 case 0: {
172 Object obj;
173 QBENCHMARK {
174 QObject::connect (&obj, SIGNAL(signal5()), &obj, SLOT(slot5()));
175 QObject::disconnect(&obj, SIGNAL(signal5()), &obj, SLOT(slot5()));
176 }
177 } break;
178 case 1: {
179 Object obj;
180 QBENCHMARK {
181 QObject::connect (&obj, SIGNAL(signal5( )), &obj, SLOT(slot5( ))); // sic: non-normalised
182 QObject::disconnect(&obj, SIGNAL(signal5( )), &obj, SLOT(slot5( ))); // sic: non-normalised
183 }
184 } break;
185 case 2: {
186 Object obj;
187 QBENCHMARK {
188 QObject::connect (&obj, &Object::signal5, &obj, &Object::slot5);
189 QObject::disconnect(&obj, &Object::signal5, &obj, &Object::slot5);
190 }
191 } break;
192 case 3: {
193 Object obj;
194 QBENCHMARK {
195 QObject::disconnect(QObject::connect(&obj, SIGNAL(signal5()), &obj, SLOT(slot5())));
196 }
197 } break;
198 case 4: {
199 Object obj;
200 QBENCHMARK {
201 QObject::disconnect(QObject::connect(&obj, SIGNAL(signal5( )), &obj, SLOT(slot5( )))); // sic: non-normalised
202 }
203 } break;
204 case 5: {
205 Object obj;
206 QBENCHMARK {
207 QObject::disconnect(QObject::connect(&obj, &Object::signal5, &obj, &Object::slot5));
208 }
209 } break;
210 case 6: {
211 Object obj;
212 Functor functor;
213 QBENCHMARK {
214 QObject::disconnect(QObject::connect(&obj, &Object::signal5, functor));
215 }
216 } break;
217 }
218}
219
220void QObjectBenchmark::connect_disconnect_benchmark()
221{
222 QFETCH(bool, w);
223 if (w) ::connect_disconnect_benchmark<ObjectW>();
224 else ::connect_disconnect_benchmark<Object>();
225}
226
227QTEST_MAIN(QObjectBenchmark)
228
229#include "main.moc"