I've got a vector of 10000 random numbers (mod 100) and I'd like to count how many pairs of two of those numbers sum to 100. I've written the following:
auto noPairsSumTo100 = 0;
const auto itEnd = end(myNums);
for (auto it1 = begin(myNums); it1 != itEnd ; ++it1) {
for (auto it2 = it1; it2 != itEnd ; ++it2) {
if (*it1 + *it2 == 100) {
noPairsSumTo100 ++;
}
}
}
On my machine this takes about 21.6 seconds to run in debug mode. If I set _ITERATOR_DEBUG_LEVEL=0 (which sets both _SECURE_SCL and _HAS_ITERATOR_DEBUGGING to 0) the execution time is reduced to ~9.5 seconds. Replacing the !=
comparisons with <
reduces the time further to ~8.5 seconds.
If I implement the same algorithm by indexing the vectors like this:
auto noPairsSumTo100 = 0;
const auto itEnd = end(myNums);
for (auto index1 = 0; index1 < noTerms; ++index1) {
for (auto index2 = index1; index2 < noTerms; ++index2) {
if (myNums[index1] + myNums[index2] == 100) {
noPairsSumTo100 ++;
}
}
}
It takes about 2.1 seconds to run in debug mode. I think this is as close as I can make the algorithms aside from iterator usage. My question is, what makes the first implementation take ~4 times longer than the second?
Note, both versions of the algorithm take about 34 milli-seconds to run in release mode, so the difference is optimised out.