【问题标题】:Is accessing an array is faster than accessing vector? [duplicate]访问数组是否比访问向量快? [复制]
【发布时间】:2011-04-26 11:59:50
【问题描述】:

可能的重复:
Using arrays or std::vectors in C++, what's the performance gap?
std::vector is so much slower than plain arrays?

内存是 1000 个元素的向量 array[] 是一个包含 1000 个元素的整数数组

for (iteration = 0; iteration < numiterations; iteration++) {
    for (j = 1; j < numints; j++) {
       memory[j] += memory[j - 1];
       //array[j] += array[j - 1];
    }
}

如果我在运行100次迭代后比较for循环的时间,访问所需的时间与vector相比非常小

为什么会这样? 因为我认为两者都需要恒定且几乎相同的时间..

【问题讨论】:

  • 你能告诉我们更多关于你测试这个平台的信息吗?编译器,优化/构建类型,诸如此类的东西?通常,vector 在调试版本中速度较慢,但​​在发布版本中与原始数组的速度相同......
  • 请参阅 [ 在 C++ 中使用数组或 std::vectors,性能差距是什么? ](stackoverflow.com/questions/381621/…)。接受的答案显示生成的程序集在向量和数组之间基本上没有区别,使用 g++ 和 -O3。
  • @ajay,什么编译器标志(包括优化设置)?而且,这是一个相当旧的版本。
  • “我认为两者都需要恒定的 [...] 时间”-> 不可能。随着序列变大,迭代序列需要更长的时间。这称为线性时间。
  • @Fred:我的意思是访问特定元素而不是整个数组或向量,无论如何,在当前上下文中,数组和向量都是固定大小的 1000 个元素。

标签: c++ arrays stdvector


【解决方案1】:

没错,它们都是常数时间。但是,向量是一个对象,重定向函数调用会受到惩罚。考虑一下这是您第一次体验 C++ 运算符重载。 vector 类重载了 [] 运算符,以实现与真实数组相似的语义。

【讨论】:

  • 错了,对不起。 std::vector 的实例仅是源代码级别的对象。一旦编译,就没有任何迹象表明它是一个对象。它像普通阵列一样平坦。剩下的唯一区别是std::vector 动态分配内存,而原始数组是用它所有的光荣数据编译的。这是允许动态调整大小所必需的。这是您应该看到的唯一罚款,您只需在施工时支付一次,而不是在访问时支付。如果您创建一个可以增长的 C 数组,那么 std::vector 的开销正好为 0(零、nada、nil)。
  • 嗯,很高兴知道。我收回我之前的声明。 +1
  • 有趣的是,通过将 C 风格的过程代码转换为更面向对象的代码,我看到了性能增益。我认为这样做的原因是把东西放在对象中告诉编译器更多关于缺乏可能的别名 - 有点像在 C99 中将 restrict 放在指针上。最后,正如 wilhelmtell 所说,对象“消失”了,但额外的信息仍然有助于优化器。
【解决方案2】:

由于std::vector 的大多数(如果不是全部)实现在内部使用T* 数组,因此在优化时使用[] 运算符访问向量元素和C 数组元素之间应该没有性能差异设置了标志。使用编译器的优化标志再次尝试测试。

但是,使用std::vector&lt;T&gt;::at 函数可能不是这种情况,因为该函数将执行边界检查。

【讨论】:

  • 你是绝对正确的,3 级优化我在两种机制上获得相同的时间..但是你能解释一下原因或指向包含原因的资源吗..?跨度>
  • 优化的构建可能是在循环之前将T* 提升到一个寄存器,并直接从寄存器中使用该指针。如果您只是传递一个普通的旧数组(地址将在寄存器中),也会发生同样的事情。在未优化的构建中,内部循环可能正在重新加载 T*
  • @ajayreddy,看看 Jerry Coffin 的回答。加速的原因可能与 operator [] 函数被优化器内联这一事实有关。
【解决方案3】:

这通常(几乎完全)取决于您是否将编译器设置为内联函数。 std::vector 使用一个函数(名为 operator[])来处理项目。如果该函数不是内联生成的,则调用该函数的开销将大大增加寻址数组中的项目所花费的时间。如果您将编译器设置为生成内联函数,则通常无法衡量两者之间的有意义差异。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-18
    • 2014-07-26
    • 1970-01-01
    • 2012-06-01
    • 2017-04-06
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多