std :: vector :: size()比手动跟踪大小要慢吗?

时间:2012-04-18 23:35:29

标签: c++ vector

每次调用时,std::vector::size()是否重新计算向量的大小,或者它是否维护仅在向量被修改时修改的计数器?例如,如果我有一个std::vector<double>成员的课程,那么在单独的计数器中跟踪其大小是否有任何速度优势?

5 个答案:

答案 0 :(得分:12)

size()保证具有恒定的时间复杂度,并且在任何理智的实现中都将尽可能快地执行操作。

答案 1 :(得分:3)

this->_Mylast - this->_myFirst 

通常涉及两次内存提取。如果您将计数保留在寄存器中,则可能更快。我说可能,因为在一个小循环中,减去的两个值将在缓存中,这并不总是比寄存器慢很多 - 取决于机器。一个聪明的编译器,使用紧密循环,无论如何都可以在寄存器中维护,如果它正确地进行数据流分析。在一个不那么小的循环中,你永远不会注意到差异。将其保存在寄存器中意味着每次迭代需要额外的操作来更新寄存器,如果它可以与其他操作并行完成,则可能是空闲的,或者它可能花费一个指令周期。因此,衡量差异很难。

无论如何,您的里程根据处理器而有所不同,即使STL的每个实现都包含相同的size()代码。

答案 2 :(得分:2)

没有必要在单独的计数器中跟踪它的大小,因为它是在向量内部完成的。这个函数的代码是这样的:

iterator begin() {return start;}
iterator end() {return finish;}
size_type size() const { return size_type(end() - begin());}

iterator start;
iterator finish;

一旦推或弹元素,变量“start”,“finish”将被更改,因此函数size()只需要减去时间。如果使用单独的计数器,当您推动或弹出元素时,您还会有一个加号或减号。

答案 3 :(得分:1)

不 - 只需使用std::vector::size()

在MSVC上,它被实现为this->_Mylast - this->_Myfirst - 你无法击败它。

答案 4 :(得分:1)

正如其他人所说,它几乎不会变得更快。只有在你的矢量大小不变的情况下,你才可以通过使用这个事实来节省一些cpu周期。实际上,你可以跳过完全查询大小。这对于渲染循环中经常重复的迭代来说可能很重要。想象一下:

之间的区别
// reset vector of size=3 to value 10

for( size_t i=0; i < myvec.size(); ++i )
{
   myvec[i] = 10.0;
}

 myvec[0] = myvec[1] = myvec[2] = 10.0;

一个典型的用例是一个3d坐标向量,一个ip-address等。但是要准备好用你自己的内部替换一些查询size()的std :: vector例程。因此,要点是,为了节省cpu周期,size运算符不是目标,寻找其他逻辑位置。当你的矢量没有改变它的大小时,即使是暂时的,你也有一只脚可以挤出一些cpu周期。

PS:Valgrind是你的朋友,先告诉你哪里优化。事实上,大小运算符经常成为最佳候选者;至少对于某些算法。

祝你好运!