Remove gui-related ifdef from testlib/qbenchmark.cpp
[profile/ivi/qtbase.git] / src / testlib / qbenchmark.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtTest module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "QtTest/qbenchmark.h"
43 #include "QtTest/private/qbenchmark_p.h"
44 #include "QtTest/private/qbenchmarkmetric_p.h"
45
46 #include <QtCore/qprocess.h>
47 #include <QtCore/qdir.h>
48 #include <QtCore/qset.h>
49 #include <QtCore/qdebug.h>
50
51 QT_BEGIN_NAMESPACE
52
53 QBenchmarkGlobalData *QBenchmarkGlobalData::current;
54
55 QBenchmarkGlobalData::QBenchmarkGlobalData()
56     : measurer(0)
57     , walltimeMinimum(-1)
58     , iterationCount(-1)
59     , medianIterationCount(-1)
60     , createChart(false)
61     , verboseOutput(false)
62     , mode_(WallTime)
63 {
64     setMode(mode_);
65 }
66
67 QBenchmarkGlobalData::~QBenchmarkGlobalData()
68 {
69     delete measurer;
70     QBenchmarkGlobalData::current = 0;
71 }
72
73 void QBenchmarkGlobalData::setMode(Mode mode)
74 {
75     mode_ = mode;
76
77     if (measurer)
78         delete measurer;
79     measurer = createMeasurer();
80 }
81
82 QBenchmarkMeasurerBase * QBenchmarkGlobalData::createMeasurer()
83 {
84     QBenchmarkMeasurerBase *measurer = 0;
85     if (0) {
86 #ifdef QTESTLIB_USE_VALGRIND
87     } else if (mode_ == CallgrindChildProcess || mode_ == CallgrindParentProcess) {
88         measurer = new QBenchmarkCallgrindMeasurer;
89 #endif
90 #ifdef HAVE_TICK_COUNTER
91     } else if (mode_ == TickCounter) {
92         measurer = new QBenchmarkTickMeasurer;
93 #endif
94     } else if (mode_ == EventCounter) {
95         measurer = new QBenchmarkEvent;
96     } else {
97         measurer =  new QBenchmarkTimeMeasurer;
98     }
99     measurer->init();
100     return measurer;
101 }
102
103 int QBenchmarkGlobalData::adjustMedianIterationCount()
104 {
105     if (medianIterationCount != -1) {
106         return medianIterationCount;
107     } else {
108         return measurer->adjustMedianCount(1);
109     }
110 }
111
112
113 QBenchmarkTestMethodData *QBenchmarkTestMethodData::current;
114
115 QBenchmarkTestMethodData::QBenchmarkTestMethodData()
116 :resultAccepted(false), runOnce(false), iterationCount(-1)
117 {
118 }
119
120 QBenchmarkTestMethodData::~QBenchmarkTestMethodData()
121 {
122     QBenchmarkTestMethodData::current = 0;
123 }
124
125 void QBenchmarkTestMethodData::beginDataRun()
126 {
127     iterationCount = adjustIterationCount(1);
128 }
129
130 void QBenchmarkTestMethodData::endDataRun()
131 {
132 }
133
134 int QBenchmarkTestMethodData::adjustIterationCount(int suggestion)
135 {
136     // Let the -iterations option override the measurer.
137     if (QBenchmarkGlobalData::current->iterationCount != -1) {
138         iterationCount = QBenchmarkGlobalData::current->iterationCount;
139     } else {
140         iterationCount = QBenchmarkGlobalData::current->measurer->adjustIterationCount(suggestion);
141     }
142
143     return iterationCount;
144 }
145
146 void QBenchmarkTestMethodData::setResult(
147     qreal value, QTest::QBenchmarkMetric metric, bool setByMacro)
148 {
149     bool accepted = false;
150
151     // Always accept the result if the iteration count has been
152     // specified on the command line with -iterations.
153     if (QBenchmarkGlobalData::current->iterationCount != -1)
154         accepted = true;
155
156     else if (QBenchmarkTestMethodData::current->runOnce || !setByMacro) {
157         iterationCount = 1;
158         accepted = true;
159     }
160
161     // Test the result directly without calling the measurer if the minimum time
162     // has been specified on the command line with -minimumvalue.
163     else if (QBenchmarkGlobalData::current->walltimeMinimum != -1)
164         accepted = (value > QBenchmarkGlobalData::current->walltimeMinimum);
165     else
166         accepted = QBenchmarkGlobalData::current->measurer->isMeasurementAccepted(value);
167
168     // Accept the result or double the number of iterations.
169     if (accepted)
170         resultAccepted = true;
171     else
172         iterationCount *= 2;
173
174     this->result = QBenchmarkResult(
175         QBenchmarkGlobalData::current->context, value, iterationCount, metric, setByMacro);
176 }
177
178 /*!
179     \class QTest::QBenchmarkIterationController
180     \internal
181
182     The QBenchmarkIterationController class is used by the QBENCHMARK macro to
183     drive the benchmarking loop. It is repsonsible for starting and stopping
184     the timing measurements as well as calling the result reporting functions.
185 */
186
187 /*! \internal
188 */
189 QTest::QBenchmarkIterationController::QBenchmarkIterationController(RunMode runMode)
190 {
191     i = 0;
192     if (runMode == RunOnce)
193         QBenchmarkTestMethodData::current->runOnce = true;
194     QTest::beginBenchmarkMeasurement();
195 }
196
197 QTest::QBenchmarkIterationController::QBenchmarkIterationController()
198 {
199     i = 0;
200     QTest::beginBenchmarkMeasurement();
201 }
202
203 /*! \internal
204 */
205 QTest::QBenchmarkIterationController::~QBenchmarkIterationController()
206 {
207     const qreal result = QTest::endBenchmarkMeasurement();
208     QBenchmarkTestMethodData::current->setResult(result, QBenchmarkGlobalData::current->measurer->metricType());
209 }
210
211 /*! \internal
212 */
213 bool QTest::QBenchmarkIterationController::isDone()
214 {
215     if (QBenchmarkTestMethodData::current->runOnce)
216         return i > 0;
217     return i >= QTest::iterationCount();
218 }
219
220 /*! \internal
221 */
222 void QTest::QBenchmarkIterationController::next()
223 {
224     ++i;
225 }
226
227 /*! \internal
228 */
229 int QTest::iterationCount()
230 {
231     return QBenchmarkTestMethodData::current->iterationCount;
232 }
233
234 /*! \internal
235 */
236 void QTest::setIterationCountHint(int count)
237 {
238     QBenchmarkTestMethodData::current->adjustIterationCount(count);
239 }
240
241 /*! \internal
242 */
243 void QTest::setIterationCount(int count)
244 {
245     QBenchmarkTestMethodData::current->iterationCount = count;
246     QBenchmarkTestMethodData::current->resultAccepted = true;
247 }
248
249 /*! \internal
250 */
251 void QTest::beginBenchmarkMeasurement()
252 {
253     QBenchmarkGlobalData::current->measurer->start();
254     // the clock is ticking after the line above, don't add code here.
255 }
256
257 /*! \internal
258 */
259 quint64 QTest::endBenchmarkMeasurement()
260 {
261     // the clock is ticking before the line below, don't add code here.
262     return QBenchmarkGlobalData::current->measurer->stop();
263 }
264
265 /*!
266     Sets the benchmark result for this test function to \a result.
267
268     Use this function if you want to report benchmark results without
269     using the QBENCHMARK macro. Use \a metric to specify how QTestLib
270     should interpret the results.
271
272     The context for the result will be the test function name and any
273     data tag from the _data function. This function can only be called
274     once in each test function, subsequent calls will replace the
275     earlier reported results.
276
277     Note that the -iterations command line argument has no effect
278     on test functions without the QBENCHMARK macro.
279
280     \since 4.7
281 */
282 void QTest::setBenchmarkResult(qreal result, QTest::QBenchmarkMetric metric)
283 {
284     QBenchmarkTestMethodData::current->setResult(result, metric, false);
285 }
286
287 template <typename T>
288 Q_TYPENAME T::value_type qAverage(const T &container)
289 {
290     Q_TYPENAME T::const_iterator it = container.constBegin();
291     Q_TYPENAME T::const_iterator end = container.constEnd();
292     Q_TYPENAME T::value_type acc = Q_TYPENAME T::value_type();
293     int count = 0;
294     while (it != end) {
295         acc += *it;
296         ++it;
297         ++count;
298     }
299     return acc / count;
300 }
301
302 QT_END_NAMESPACE