eoi*_*lan 5 c++ iterator visual-c++ visual-studio-2012
我有一个10000个随机数(mod 100)的向量,我想计算两个数字中有多少对加起来等于100。我编写了以下内容:
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 ++;
}
}
}
Run Code Online (Sandbox Code Playgroud)
在我的机器上,以调试模式运行大约需要21.6秒。如果我将_ITERATOR_DEBUG_LEVEL = 0设置(将_SECURE_SCL和_HAS_ITERATOR_DEBUGGING都设置为0),则执行时间将减少到9.5秒。更换!=比较用<进一步减少了的时间到〜8.5秒。
如果我通过对向量进行索引来实现相同的算法,如下所示:
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 ++;
}
}
}
Run Code Online (Sandbox Code Playgroud)
在调试模式下运行大约需要2.1秒。我认为除了迭代器用法之外,这与我可以使算法尽可能接近。我的问题是,是什么使第一个实现比第二个实现花费了大约4倍的时间?
请注意,两种版本的算法都需要大约34毫秒才能在发布模式下运行,因此差异得到了优化。
除了边界检查之外,STL 代码的调试版本会产生大量的函数调用。一些无辜的台词,例如:
if (a.empty())
Run Code Online (Sandbox Code Playgroud)
可以产生多达 8 个(或更多)函数调用。一些(全部?)STL 实现根本没有针对调试构建进行优化。
STL 的一个常见性能问题是开发人员认为函数内联总是有效。事实并非如此。如果调用了太多内联函数,则底部函数不会被内联,并且函数调用开销会对性能造成巨大影响。当有容器的容器时,这种情况很常见:
map< string, map< int, string>>
Run Code Online (Sandbox Code Playgroud)
对外部映射的操作可能会导致内联函数保持正常函数的状态。