source: trunk/src/testlib/qbenchmark.cpp@ 792

Last change on this file since 792 was 651, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.2 sources.

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