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

Last change on this file since 385 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

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