我做了一个大的整数向量的广泛的计算.向量的大小在计算过程中不会改变.向量的大小是经常访问的代码.什么是更快的一般:
vector::size()
vectorSize
我知道编译器通常在设置正确的编译器标志时内联size()函数,但是,这并不能保证。
size()
ar5n3qh51#
有意思的问题。那么,接下来会发生什么呢?如果你用gdb调试,你会看到类似3个成员变量的内容(名称不准确):
_M_begin
_M_end
_M_capacity
因此,vector<T,Alloc>::size()的实现通常被简化为:
vector<T,Alloc>::size()
return _M_end - _M_begin; // Note: _Mylast - _Myfirst in VC 2008
字符串现在,在考虑可能的实际优化时,有两件事需要考虑:
换句话说:
size
vector
这是一个微优化。一般来说,它不会引起注意,因为性能无关紧要,或者编译器会执行它。在编译器不应用优化的关键循环中,它可以是一个显著的改进。
kuarbcqp2#
根据我对1998年C++规范的理解,vector<T>::size()需要常数时间,而不是线性时间。因此,这个问题可能归结为读取局部变量是否比调用一个工作量很小的函数更快。因此,我认为将向量的size()存储在一个局部变量中会使程序的速度提高一点,因为你只会调用这个函数一次(因此执行所需的时间很小),而不是多次。
vector<T>::size()
628mspwn3#
vector::size()的性能:是否与阅读变量一样快?大概不会吧。有关系吗大概不会吧。除非每次迭代所做的工作很小(如一个或两个整数运算),否则开销将微不足道。
7z5jn7bk4#
在我见过的每个实现中,看到vector::size()执行end()和begin()的减法,即它不如阅读变量快。当实现一个向量时,实现者必须在哪一个最快之间做出选择,end()或size(),即存储初始化元素的数量或指向最后一个初始化元素之后的元素的指针/迭代器。换句话说,通过使用迭代器进行迭代。如果你担心size()的性能,可以像这样编写基于索引的for循环;
end()
begin()
size(),
for (size_t i = 0, i_end = container.size(); i < i_end; ++i){ // do something performance critical }
字符串
64jmpszr5#
我总是保存vector.size()在一个局部变量中(如果大小在循环中没有改变!)。在每次迭代中调用它比保存在局部变量中要快,至少我是这样经历的。我不能给给予你任何真实的数字,因为我很久以前就测试过这个了,但是从我的记忆中,它产生了明显的差异(但是可能只在调试模式下),特别是在嵌套循环的时候。对于所有抱怨微优化的人:这是一个单一的额外的代码行,没有引入任何缺点。
vector.size()
5t7ly7z56#
你可以为你的循环体写一个functor,然后通过std::for_each调用它。它会为你执行迭代,然后你的问题就没有意义了。然而,你为每个循环迭代引入了一个函数调用(可能会也可能不会内联),所以如果你没有得到你期望的性能,你最好对它进行分析。
std::for_each
xcitsw887#
在考虑这种微优化之前,一定要先了解应用程序的配置文件。记住,即使它执行减法,编译器仍然可以轻松地以多种方式优化它,从而消除任何性能损失。
7条答案
按热度按时间ar5n3qh51#
有意思的问题。
那么,接下来会发生什么呢?如果你用gdb调试,你会看到类似3个成员变量的内容(名称不准确):
_M_begin
:指向动态数组第一个元素的指针_M_end
:指针一通过动态数组的最后一个元素_M_capacity
:指针一,指针指向可存储在动态数组中的最后一个元素因此,
vector<T,Alloc>::size()
的实现通常被简化为:字符串
现在,在考虑可能的实际优化时,有两件事需要考虑:
换句话说:
size
,则很有可能它的速度会与编译器获取它的速度一样快。vector
;如果不能,则无法缓存该变量,并且每次都需要执行内存读取(L1)。这是一个微优化。一般来说,它不会引起注意,因为性能无关紧要,或者编译器会执行它。在编译器不应用优化的关键循环中,它可以是一个显著的改进。
kuarbcqp2#
根据我对1998年C++规范的理解,
vector<T>::size()
需要常数时间,而不是线性时间。因此,这个问题可能归结为读取局部变量是否比调用一个工作量很小的函数更快。因此,我认为将向量的
size()
存储在一个局部变量中会使程序的速度提高一点,因为你只会调用这个函数一次(因此执行所需的时间很小),而不是多次。628mspwn3#
vector::size()的性能:是否与阅读变量一样快?
大概不会吧。
有关系吗
大概不会吧。
除非每次迭代所做的工作很小(如一个或两个整数运算),否则开销将微不足道。
7z5jn7bk4#
在我见过的每个实现中,看到
vector::size()
执行end()
和begin()
的减法,即它不如阅读变量快。当实现一个向量时,实现者必须在哪一个最快之间做出选择,
end()
或size(),
即存储初始化元素的数量或指向最后一个初始化元素之后的元素的指针/迭代器。换句话说,通过使用迭代器进行迭代。如果你担心size()的性能,可以像这样编写基于索引的for循环;
字符串
64jmpszr5#
我总是保存
vector.size()
在一个局部变量中(如果大小在循环中没有改变!)。在每次迭代中调用它比保存在局部变量中要快,至少我是这样经历的。
我不能给给予你任何真实的数字,因为我很久以前就测试过这个了,但是从我的记忆中,它产生了明显的差异(但是可能只在调试模式下),特别是在嵌套循环的时候。
对于所有抱怨微优化的人:
这是一个单一的额外的代码行,没有引入任何缺点。
5t7ly7z56#
你可以为你的循环体写一个functor,然后通过
std::for_each
调用它。它会为你执行迭代,然后你的问题就没有意义了。然而,你为每个循环迭代引入了一个函数调用(可能会也可能不会内联),所以如果你没有得到你期望的性能,你最好对它进行分析。xcitsw887#
在考虑这种微优化之前,一定要先了解应用程序的配置文件。记住,即使它执行减法,编译器仍然可以轻松地以多种方式优化它,从而消除任何性能损失。