summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2021-07-21 14:24:41 +0200
committerEdward Welbourne <edward.welbourne@qt.io>2021-07-23 17:19:12 +0200
commit23434f487b05c5230085f61f3f7370e74d3eb6ca (patch)
tree397beaf832df9b6f4759a6396947483d2a6c57f0 /tests
parentd0f9743d3b6dce647f4cbb6d2b58ce6660f61b62 (diff)
QMap benchmark: use unsigned accumulators and check them
The sum of the first 100000 naturals is more than 2^32, so using an int accumulator to collect the values is susceptible to overflow, which is UB for signed integral types. So switch to an unsigned type. We don't care about the actual sum, only having the various map entries we fetch "used". Since unsigned arithmetic is well-defined even when it overflows, we can calculate the expected sum and verify it, to ensure that no matter how clever the optimizer, it won't throw out the accumulator as written but not read (and then optimize out all the tested code). As a drive-by, rename one of the accumulators to match the rest. Change-Id: I93a2825247c96ca88fe52fdb7ce1e5456eebad54 Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
Diffstat (limited to 'tests')
-rw-r--r--tests/benchmarks/corelib/tools/qmap/tst_bench_qmap.cpp16
1 files changed, 12 insertions, 4 deletions
diff --git a/tests/benchmarks/corelib/tools/qmap/tst_bench_qmap.cpp b/tests/benchmarks/corelib/tools/qmap/tst_bench_qmap.cpp
index b3b2934580..48321d9eb2 100644
--- a/tests/benchmarks/corelib/tools/qmap/tst_bench_qmap.cpp
+++ b/tests/benchmarks/corelib/tools/qmap/tst_bench_qmap.cpp
@@ -84,6 +84,8 @@ QStringList tst_QMap::helloEachWorld(int count)
}
constexpr int huge = 100000; // one hundred thousand; simple integral data tests
+// Sum of i with 0 <= i < huge; overflows, but that's OK as long as it's unsigned:
+constexpr uint hugeSum = (uint(huge) / 2) * uint(huge - 1);
constexpr int bigish = 5000; // five thousand; tests using XString's expensive <
void tst_QMap::insertion_int_int()
@@ -159,11 +161,13 @@ void tst_QMap::lookup_int_int()
for (int i = 0; i < huge; ++i)
map.insert(i, i);
- int sum = 0;
+ uint sum = 0, count = 0;
QBENCHMARK {
for (int i = 0; i < huge; ++i)
sum += map.value(i);
+ ++count;
}
+ QCOMPARE(sum, hugeSum * count);
}
void tst_QMap::lookup_int_string()
@@ -186,11 +190,13 @@ void tst_QMap::lookup_string_int()
for (int i = 1; i < huge; ++i)
map.insert(names.at(i), i);
- int sum = 0;
+ uint sum = 0, count = 0;
QBENCHMARK {
for (int i = 1; i < huge; ++i)
sum += map.value(names.at(i));
+ ++count;
}
+ QCOMPARE(sum, hugeSum * count);
}
// iteration speed doesn't depend on the type of the map.
@@ -200,17 +206,19 @@ void tst_QMap::iteration()
for (int i = 0; i < huge; ++i)
map.insert(i, i);
- int j = 0;
+ uint sum = 0, count = 0;
QBENCHMARK {
for (int i = 0; i < 100; ++i) {
QMap<int, int>::const_iterator it = map.constBegin();
QMap<int, int>::const_iterator end = map.constEnd();
while (it != end) {
- j += *it;
+ sum += *it;
++it;
}
}
+ ++count;
}
+ QCOMPARE(sum, hugeSum * 100u * count);
}
void tst_QMap::toStdMap()