qbenchmark.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/testlib/qbenchmark.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
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 QtTest module of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL$-
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 Lesser General Public License Usage-
18** Alternatively, this file may be used under the terms of the GNU Lesser-
19** General Public License version 3 as published by the Free Software-
20** Foundation and appearing in the file LICENSE.LGPL3 included in the-
21** packaging of this file. Please review the following information to-
22** ensure the GNU Lesser General Public License version 3 requirements-
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.-
24**-
25** GNU General Public License Usage-
26** Alternatively, this file may be used under the terms of the GNU-
27** General Public License version 2.0 or (at your option) the GNU General-
28** Public license version 3 or any later version approved by the KDE Free-
29** Qt Foundation. The licenses are as published by the Free Software-
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3-
31** included in the packaging of this file. Please review the following-
32** information to ensure the GNU General Public License requirements will-
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and-
34** https://www.gnu.org/licenses/gpl-3.0.html.-
35**-
36** $QT_END_LICENSE$-
37**-
38****************************************************************************/-
39-
40#include <QtTest/qbenchmark.h>-
41#include <QtTest/private/qbenchmark_p.h>-
42#include <QtTest/private/qbenchmarkmetric_p.h>-
43-
44#include <QtCore/qprocess.h>-
45#include <QtCore/qdir.h>-
46#include <QtCore/qset.h>-
47#include <QtCore/qdebug.h>-
48-
49QT_BEGIN_NAMESPACE-
50-
51QBenchmarkGlobalData *QBenchmarkGlobalData::current;-
52-
53QBenchmarkGlobalData::QBenchmarkGlobalData()-
54 : measurer(0)-
55 , walltimeMinimum(-1)-
56 , iterationCount(-1)-
57 , medianIterationCount(-1)-
58 , createChart(false)-
59 , verboseOutput(false)-
60 , minimumTotal(-1)-
61 , mode_(WallTime)-
62{-
63 setMode(mode_);-
64}-
65-
66QBenchmarkGlobalData::~QBenchmarkGlobalData()-
67{-
68 delete measurer;-
69 QBenchmarkGlobalData::current = 0;-
70}-
71-
72void QBenchmarkGlobalData::setMode(Mode mode)-
73{-
74 mode_ = mode;-
75-
76 if (measurer)-
77 delete measurer;-
78 measurer = createMeasurer();-
79}-
80-
81QBenchmarkMeasurerBase * QBenchmarkGlobalData::createMeasurer()-
82{-
83 QBenchmarkMeasurerBase *measurer = 0;-
84 if (0) {
dead code: { }
-
85#ifdef QTESTLIB_USE_VALGRIND
dead code: { }
-
86 } else if (mode_ == CallgrindChildProcess || mode_ == CallgrindParentProcess) {
dead code: { }
-
87 measurer = new QBenchmarkCallgrindMeasurer;-
88#endif-
89#ifdef QTESTLIB_USE_PERF_EVENTS-
90 } else if (mode_ == PerfCounter) {-
91 measurer = new QBenchmarkPerfEventsMeasurer;-
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-
123QBenchmarkTestMethodData::~QBenchmarkTestMethodData()-
124{-
125 QBenchmarkTestMethodData::current = 0;-
126}-
127-
128void QBenchmarkTestMethodData::beginDataRun()-
129{-
130 iterationCount = adjustIterationCount(1);-
131}-
132-
133void QBenchmarkTestMethodData::endDataRun()-
134{-
135}-
136-
137int QBenchmarkTestMethodData::adjustIterationCount(int suggestion)-
138{-
139 // Let the -iterations option override the measurer.-
140 if (QBenchmarkGlobalData::current->iterationCount != -1) {-
141 iterationCount = QBenchmarkGlobalData::current->iterationCount;-
142 } else {-
143 iterationCount = QBenchmarkGlobalData::current->measurer->adjustIterationCount(suggestion);-
144 }-
145-
146 return iterationCount;-
147}-
148-
149void QBenchmarkTestMethodData::setResult(-
150 qreal value, QTest::QBenchmarkMetric metric, bool setByMacro)-
151{-
152 bool accepted = false;-
153-
154 // Always accept the result if the iteration count has been-
155 // specified on the command line with -iterations.-
156 if (QBenchmarkGlobalData::current->iterationCount != -1)-
157 accepted = true;-
158-
159 else if (QBenchmarkTestMethodData::current->runOnce || !setByMacro) {-
160 iterationCount = 1;-
161 accepted = true;-
162 }-
163-
164 // Test the result directly without calling the measurer if the minimum time-
165 // has been specified on the command line with -minimumvalue.-
166 else if (QBenchmarkGlobalData::current->walltimeMinimum != -1)-
167 accepted = (value > QBenchmarkGlobalData::current->walltimeMinimum);-
168 else-
169 accepted = QBenchmarkGlobalData::current->measurer->isMeasurementAccepted(value);-
170-
171 // Accept the result or double the number of iterations.-
172 if (accepted)-
173 resultAccepted = true;-
174 else-
175 iterationCount *= 2;-
176-
177 this->result = QBenchmarkResult(-
178 QBenchmarkGlobalData::current->context, value, iterationCount, metric, setByMacro);-
179}-
180-
181/*!-
182 \class QTest::QBenchmarkIterationController-
183 \internal-
184-
185 The QBenchmarkIterationController class is used by the QBENCHMARK macro to-
186 drive the benchmarking loop. It is repsonsible for starting and stopping-
187 the timing measurements as well as calling the result reporting functions.-
188*/-
189-
190/*! \internal-
191*/-
192QTest::QBenchmarkIterationController::QBenchmarkIterationController(RunMode runMode)-
193{-
194 i = 0;-
195 if (runMode == RunOnce)-
196 QBenchmarkTestMethodData::current->runOnce = true;-
197 QTest::beginBenchmarkMeasurement();-
198}-
199-
200QTest::QBenchmarkIterationController::QBenchmarkIterationController()-
201{-
202 i = 0;-
203 QTest::beginBenchmarkMeasurement();-
204}-
205-
206/*! \internal-
207*/-
208QTest::QBenchmarkIterationController::~QBenchmarkIterationController()-
209{-
210 const qreal result = QTest::endBenchmarkMeasurement();-
211 QBenchmarkTestMethodData::current->setResult(result, QBenchmarkGlobalData::current->measurer->metricType());-
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*/-
262quint64 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/*!-
269 Sets the benchmark result for this test function to \a result.-
270-
271 Use this function if you want to report benchmark results without-
272 using the QBENCHMARK macro. Use \a metric to specify how Qt Test-
273 should interpret the results.-
274-
275 The context for the result will be the test function name and any-
276 data tag from the _data function. This function can only be called-
277 once in each test function, subsequent calls will replace the-
278 earlier reported results.-
279-
280 Note that the -iterations command line argument has no effect-
281 on test functions without the QBENCHMARK macro.-
282-
283 \since 4.7-
284*/-
285void QTest::setBenchmarkResult(qreal result, QTest::QBenchmarkMetric metric)-
286{-
287 QBenchmarkTestMethodData::current->setResult(result, metric, false);-
288}-
289-
290template <typename T>-
291typename T::value_type qAverage(const T &container)-
292{-
293 typename T::const_iterator it = container.constBegin();-
294 typename T::const_iterator end = container.constEnd();-
295 typename T::value_type acc = typename T::value_type();-
296 int count = 0;-
297 while (it != end) {-
298 acc += *it;-
299 ++it;-
300 ++count;-
301 }-
302 return acc / count;-
303}-
304-
305QT_END_NAMESPACE-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9