1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the test suite of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
41 #include <QDeclarativeEngine>
42 #include <QDeclarativeComponent>
44 #include <QApplication>
46 #include <QDeclarativeContext>
47 #include <QGraphicsScene>
48 #include <QGraphicsRectItem>
50 class Timer : public QObject
53 Q_PROPERTY(QDeclarativeComponent *component READ component WRITE setComponent)
58 QDeclarativeComponent *component() const;
59 void setComponent(QDeclarativeComponent *);
61 static Timer *timerInstance();
65 bool willParent() const;
66 void setWillParent(bool p);
69 void runTest(QDeclarativeContext *, uint);
71 QDeclarativeComponent *m_component;
72 static Timer *m_timer;
75 QGraphicsScene m_scene;
76 QGraphicsRectItem m_item;
78 QML_DECLARE_TYPE(Timer);
80 Timer *Timer::m_timer = 0;
83 : m_component(0), m_willparent(false)
86 qWarning("Timer: Timer already registered");
89 m_scene.setItemIndexMethod(QGraphicsScene::NoIndex);
90 m_scene.addItem(&m_item);
93 QDeclarativeComponent *Timer::component() const
98 void Timer::setComponent(QDeclarativeComponent *c)
103 Timer *Timer::timerInstance()
108 void Timer::run(uint iterations)
110 QDeclarativeContext context(qmlContext(this));
112 QObject *o = m_component->create(&context);
113 QGraphicsObject *go = qobject_cast<QGraphicsObject *>(o);
114 if (m_willparent && go)
115 go->setParentItem(&m_item);
118 runTest(&context, iterations);
121 bool Timer::willParent() const
126 void Timer::setWillParent(bool p)
131 void Timer::runTest(QDeclarativeContext *context, uint iterations)
135 for (uint ii = 0; ii < iterations; ++ii) {
136 QObject *o = m_component->create(context);
137 QGraphicsObject *go = qobject_cast<QGraphicsObject *>(o);
138 if (m_willparent && go)
139 go->setParentItem(&m_item);
145 qWarning() << "Total:" << e << "ms, Per iteration:" << qreal(e) / qreal(iterations) << "ms";
149 void usage(const char *name)
151 qWarning("Usage: %s [-iterations <count>] [-parent] <qml file>\n", name);
153 qWarning("qmltime is a tool for benchmarking the runtime cost of instantiating\n"
154 "a QML component. It is typically run as follows:\n"
156 "%s path/to/benchmark.qml\n"
158 "If the -parent option is specified, the component being measured will also\n"
159 "be parented to an item already in the scene.\n"
161 "If the -iterations option is specified, the benchmark will run the specified\n"
162 "number of iterations. If -iterations is not specified, 1024 iterations\n"
165 "qmltime expects the file to be benchmarked to contain a certain structure.\n"
166 "Specifically, it requires the presence of a QmlTime.Timer element. For example,\n"
167 "say we wanted to benchmark the following list delegate:\n"
170 " color: \"green\"\n"
171 " width: 400; height: 100\n"
173 " anchors.centerIn: parent\n"
178 "we would create a benchmark file that looks like this:\n"
180 "import QtQuick 1.0\n"
181 "import QmlTime 1.0 as QmlTime\n"
185 " property string name: \"Bob Smith\"\n"
188 " component: Rectangle {\n"
189 " color: \"green\"\n"
190 " width: 400; height: 100\n"
192 " anchors.centerIn: parent\n"
199 "The outer Item functions as a dummy data provider for any additional\n"
200 "data required by the bindings in the component being benchmarked (in the\n"
201 "example above we provide a \"name\" property).\n"
203 "When started, the component is instantiated once before running\n"
204 "the benchmark, which means that the reported time does not include\n"
205 "compile time (as the results of compilation are cached internally).\n"
206 "In this sense the times reported by qmltime best correspond to the\n"
207 "costs associated with delegate creation in the view classes, where the\n"
208 "same delegate is instantiated over and over. Conversely, it is not a\n"
209 "good approximation for e.g. Loader, which typically only instantiates\n"
210 "an element once (and so for Loader the compile time is very relevant\n"
211 "to the overall cost).", name);
216 int main(int argc, char ** argv)
218 QApplication app(argc, argv);
220 qmlRegisterType<Timer>("QmlTime", 1, 0, "Timer");
222 uint iterations = 1024;
224 bool willParent = false;
226 for (int ii = 1; ii < argc; ++ii) {
227 QByteArray arg(argv[ii]);
229 if (arg == "-iterations") {
232 QByteArray its(argv[ii]);
234 iterations = its.toUInt(&ok);
240 } else if (arg == "-parent") {
242 } else if (arg == "-help") {
245 filename = QLatin1String(argv[ii]);
249 if (filename.isEmpty())
251 filename = QLatin1String("./tests/item_creation/data.qml");
256 QDeclarativeEngine engine;
257 QDeclarativeComponent component(&engine, filename);
258 if (component.isError()) {
259 qWarning() << component.errors();
263 QObject *obj = component.create();
265 qWarning() << component.errors();
269 Timer *timer = Timer::timerInstance();
271 qWarning() << "A Tester.Timer instance is required.";
278 timer->setWillParent(willParent);
280 if (!timer->component()) {
281 qWarning() << "The timer has no component";
289 timer->run(iterations);
294 #include "qmltime.moc"