From 7aa2d76dfc4a107f38c5cb0aac00a0b31d0fbbb6 Mon Sep 17 00:00:00 2001 From: Morten Sorvig Date: Mon, 10 Aug 2009 10:14:12 +0200 Subject: Add QBENCMARK_ONCE to QTestLib. The code block associated with QBENCHMARK_ONCE macro will only be executed once, whether the backend returns a valid result or not. The "-iterations" command line argument is also ignored. This is useful for benchmarking code that has side effects. Revby: jasplin --- src/testlib/qbenchmark.cpp | 13 +++++++++++-- src/testlib/qbenchmark.h | 10 ++++++++-- src/testlib/qbenchmark_p.h | 1 + src/testlib/qtestcase.cpp | 19 +++++++++++++++++++ .../benchlibwalltime/tst_benchlibwalltime.cpp | 11 +++++++++++ tests/auto/selftests/expected_benchlibwalltime.txt | 5 ++++- 6 files changed, 54 insertions(+), 5 deletions(-) diff --git a/src/testlib/qbenchmark.cpp b/src/testlib/qbenchmark.cpp index 9cdf232..bad3379 100644 --- a/src/testlib/qbenchmark.cpp +++ b/src/testlib/qbenchmark.cpp @@ -116,7 +116,7 @@ int QBenchmarkGlobalData::adjustMedianIterationCount() QBenchmarkTestMethodData *QBenchmarkTestMethodData::current; QBenchmarkTestMethodData::QBenchmarkTestMethodData() -:resultAccepted(false), iterationCount(-1) +:resultAccepted(false), runOnce(false), iterationCount(-1) { } @@ -157,6 +157,11 @@ void QBenchmarkTestMethodData::setResult(qint64 value) if (QBenchmarkGlobalData::current->iterationCount != -1) accepted = true; + if (QBenchmarkTestMethodData::current->runOnce) { + iterationCount = 1; + accepted = true; + } + // Test the result directly without calling the measurer if the minimum time // has been specifed on the command line with -minimumvalue. else if (QBenchmarkGlobalData::current->walltimeMinimum != -1) @@ -179,10 +184,12 @@ void QBenchmarkTestMethodData::setResult(qint64 value) drive the benchmarking loop. It is repsonsible for starting and stopping the timing measurements as well as calling the result reporting functions. */ -QTest::QBenchmarkIterationController::QBenchmarkIterationController() +QTest::QBenchmarkIterationController::QBenchmarkIterationController(RunMode runMode) { QTest::beginBenchmarkMeasurement(); i = 0; + if (runMode == RunOnce) + QBenchmarkTestMethodData::current->runOnce = true; } /*! \internal */ @@ -195,6 +202,8 @@ QTest::QBenchmarkIterationController::~QBenchmarkIterationController() */ bool QTest::QBenchmarkIterationController::isDone() { + if (QBenchmarkTestMethodData::current->runOnce) + return i > 0; return i >= QTest::iterationCount(); } diff --git a/src/testlib/qbenchmark.h b/src/testlib/qbenchmark.h index c06bfc0..87d34e7 100644 --- a/src/testlib/qbenchmark.h +++ b/src/testlib/qbenchmark.h @@ -64,7 +64,8 @@ namespace QTest class Q_TESTLIB_EXPORT QBenchmarkIterationController { public: - QBenchmarkIterationController(); + enum RunMode { RepeatUntilValidMeasurement, RunOnce }; + QBenchmarkIterationController(RunMode runMode); ~QBenchmarkIterationController(); bool isDone(); void next(); @@ -74,7 +75,12 @@ public: } #define QBENCHMARK \ - for (QTest::QBenchmarkIterationController __iteration_controller; __iteration_controller.isDone() == false; __iteration_controller.next()) + for (QTest::QBenchmarkIterationController __iteration_controller(QTest::QBenchmarkIterationController::RepeatUntilValidMeasurement); \ + __iteration_controller.isDone() == false; __iteration_controller.next()) + +#define QBENCHMARK_ONCE \ + for (QTest::QBenchmarkIterationController __iteration_controller(QTest::QBenchmarkIterationController::RunOnce); \ + __iteration_controller.isDone() == false; __iteration_controller.next()) QT_END_NAMESPACE diff --git a/src/testlib/qbenchmark_p.h b/src/testlib/qbenchmark_p.h index 25f9cdc..185d656 100644 --- a/src/testlib/qbenchmark_p.h +++ b/src/testlib/qbenchmark_p.h @@ -171,6 +171,7 @@ public: QBenchmarkResult result; bool resultAccepted; + bool runOnce; int iterationCount; }; diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 1866197..21a686e 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -351,6 +351,25 @@ QT_BEGIN_NAMESPACE {Chapter 5: Writing a Benchmark}{Writing a Benchmark} */ +/*! + \macro QBENCHMARK_ONCE + + \relates QTest + + This macro is used to measure the performance of code within a test. + The code to be benchmarked is contained within a code block following + this macro. + + Unlike QBENCHMARK, the contents of the contained code block is only run + once. The elapsed time will be reported as "0" if it's to short to + be measured by the selected backend. (Use) + + \sa {QTestLib Manual#Creating a Benchmark}{Creating a Benchmark}, + {Chapter 5: Writing a Benchmark}{Writing a Benchmark} +*/ + + + /*! \enum QTest::SkipMode This enum describes the modes for skipping tests during execution diff --git a/tests/auto/selftests/benchlibwalltime/tst_benchlibwalltime.cpp b/tests/auto/selftests/benchlibwalltime/tst_benchlibwalltime.cpp index de65599..8474144f 100644 --- a/tests/auto/selftests/benchlibwalltime/tst_benchlibwalltime.cpp +++ b/tests/auto/selftests/benchlibwalltime/tst_benchlibwalltime.cpp @@ -50,6 +50,7 @@ class tst_BenchlibWalltime: public QObject private slots: void waitForOneThousand(); void waitForFourThousand(); + void qbenchmark_once(); }; void tst_BenchlibWalltime::waitForOneThousand() @@ -66,6 +67,16 @@ void tst_BenchlibWalltime::waitForFourThousand() } } +void tst_BenchlibWalltime::qbenchmark_once() +{ + int iterations = 0; + QBENCHMARK_ONCE { + ++iterations; + } + QCOMPARE(iterations, 1); +} + + QTEST_MAIN(tst_BenchlibWalltime) #include "tst_benchlibwalltime.moc" diff --git a/tests/auto/selftests/expected_benchlibwalltime.txt b/tests/auto/selftests/expected_benchlibwalltime.txt index 03f2465..ec2d020 100644 --- a/tests/auto/selftests/expected_benchlibwalltime.txt +++ b/tests/auto/selftests/expected_benchlibwalltime.txt @@ -7,6 +7,9 @@ PASS : tst_BenchlibWalltime::waitForOneThousand() RESULT : tst_BenchlibWalltime::waitForFourThousand(): 4,000 msec per iteration (total: 4000, iterations: 1) PASS : tst_BenchlibWalltime::waitForFourThousand() +RESULT : tst_BenchlibWalltime::qbenchmark_once(): + 0 msec per iteration (total: 0, iterations: 1) +PASS : tst_BenchlibWalltime::qbenchmark_once() PASS : tst_BenchlibWalltime::cleanupTestCase() -Totals: 4 passed, 0 failed, 0 skipped +Totals: 5 passed, 0 failed, 0 skipped ********* Finished testing of tst_BenchlibWalltime ********* -- cgit v0.12