我已经对整数的大向量进行了广泛的计算。矢量大小在计算期间不会更改。向量的大小经常被代码访问。通常更快的方法是:使用vector::size()
函数或使用辅助常数vectorSize
存储向量的大小?我知道编译器通常可以在设置适当的编译器标志时内联size()
函数,但是,使函数内联是编译器可以做但不能强制执行的事情。
有趣的问题。
那么,会发生什么?好吧,如果您使用gdb进行调试,您将看到3个成员变量(名称不正确):
_M_begin
:指向动态数组的第一个元素的指针_M_end
:指针经过动态数组的最后一个元素_M_capacity
:指针可以在动态数组中存储的最后一个元素之后经过]因此通常将vector<T,Alloc>::size()
的实现简化为:
return _M_end - _M_begin; // Note: _Mylast - _Myfirst in VC 2008
现在,考虑实际可能的优化时,有两件事要考虑:
换句话说:
size
,很有可能它会和编译器所能得到的一样快。vector
;如果不是,则无法缓存该变量,并且每次都需要执行内存读取(L1)。这是微观优化。通常,由于性能无关紧要或因为编译器无论如何都会执行它,所以它不会引起注意。在编译器未应用优化的关键循环中,这可能是一个重大改进。
据我了解1998 C ++规范,vector<T>::size()
需要恒定的时间,而不是线性时间。因此,这个问题可能归结为:读取局部变量是否比调用一个工作量很小的函数要快。
vector :: size()的性能:和读取变量一样快?
在我执行的每个实现中,看到vector::size()
都执行end()
和begin()
的减法,即它不如读取变量快。
[实现矢量时,实现者必须在最快的end()
或size(),
之间进行选择,即在最后一个初始化元素之后存储初始化元素的数量或指向该元素的指针/迭代器。换一种说法;通过使用迭代器进行迭代。
我总是将vector.size()
保存在局部变量中(如果大小在循环内没有改变!)。在每次迭代中调用它与将其保存在局部变量中可以更快。至少,这就是我的经历。我无法提供任何实际数字,因为我很久以前就对此进行了测试。但是,据我所记得,它产生了显着的差异(但是可能仅在调试模式下),特别是在嵌套循环时。
您可以为循环主体编写一个函子,然后通过std::for_each
对其进行调用。它为您进行迭代,然后您的问题变得毫无意义。但是,您在每次循环迭代时都会引入一个函数调用(可能会内联,也可能不会内联),因此,如果无法获得预期的性能,则最好对其进行概要分析。
在查看这种微优化之前,请始终获取应用程序的配置文件。请记住,即使执行减法运算,编译器仍可以通过许多方式轻松优化它,从而消除任何性能损失。