std :: array vs array performance

时间:2015-05-15 15:27:41

标签: c++ c++11 stdarray

如果我想构建一个非常简单的数组,如

int myArray[3] = {1,2,3};

我应该使用std::array吗?

std::array<int, 3> a = {{1, 2, 3}};

使用std :: array比使用常规的有什么好处?性能更高吗?只是更容易处理复制/访问?

5 个答案:

答案 0 :(得分:60)

  

使用std::array优于常规优势有什么好处?

它具有友好的值语义,因此可以通过值传递给函数或从函数返回。它的界面使得查找大小更加方便,并且可以使用基于STL样式的迭代器算法。

  

性能更高吗?

它应该完全一样。根据定义,它是一个简单的聚合,包含一个数组作为其唯一成员。

  

更容易处理复制/访问?

答案 1 :(得分:23)

std::array是一个围绕C风格数组的非常薄的包装器,基本上定义为

template<typename T, size_t N>
class array
{
public:
    T _data[N];
    T& operator[](size_t);
    const T& operator[](size_t) const;
    // other member functions and typedefs
};

它是一个aggregate,它允许你使用它几乎像一个基本类型(即你可以传递值,分配等,而标准的C数组不能直接分配或复制到另一个数组)。您应该看看一些标准实现(从您喜欢的IDE跳转到定义或直接打开<array>),它是C ++标准库的一部分,非常容易阅读和理解。

答案 2 :(得分:17)

std::array被设计为C数组的零开销包装器,为其提供“正常”值,如其他C ++容器的语义。

在您仍然享受额外功能的同时,您不应该注意到运行时性能的任何差异。

使用std::array而不是int[]样式数组是一个好主意,如果你有C ++ 11或者手头有提升。

答案 3 :(得分:3)

std::array具有值语义,而原始数组则没有。这意味着您可以复制std::array并将其视为原始值。您可以通过值或引用作为函数参数接收它们,并且可以按值返回它们。

如果您从不复制std::array,那么与原始数组没有性能差异。如果你确实需要制作副本,那么std::array将会做正确的事情,并且仍然可以提供相同的效果。

答案 4 :(得分:2)

  
    

表现更好吗?

  
     

应该完全一样。根据定义,它是一个简单的聚合,其中包含数组作为其唯一成员。

情况似乎更加复杂,因为根据特定平台,std :: array与C-array相比并不总是产生相同的汇编代码。

我在godbolt.org上测试了这种特定情况:

#include <array>
void test(double* const C, const double* const A,
           const double* const B, const size_t size) {
  for (size_t i = 0; i < size; i++) {
    //double arr[2] = {0.e0};//
    std::array<double, 2> arr = {0.e0};//different to double arr[2] for some compiler
    for (size_t j = 0; j < size; j++) {
      arr[0] += A[i] * B[j];
      arr[1] += A[j] * B[i];
    }
    C[i] += arr[0];
    C[i] += arr[1];
  }
}

GCC和Clang为C-array版本和Clang版本生成相同的汇编代码 std :: array版本。

但是,对于每个阵列版本,MSVC和ICPC产生不同的汇编代码。 (我用-Ofast和-Os来测试ICPC19;使用MSVC -Ox和-Os来测试)

我不知道为什么会这样(我确实希望std :: array和c-array的行为完全相同)。 也许采用了不同的优化策略。

额外一点: 使用

的icpc中似乎有一个错误
#pragma simd 

在某些情况下使用c数组时进行矢量化 (C数组代码产生错误的输出; std :: array版本运行正常)。 不幸的是,我还没有一个可行的最小示例,因为我在优化相当复杂的代码时发现了这个问题。 当我确定我不会只是误解了有关c_array / std :: array和#pragma simd的信息时,我将向英特尔提交错误报告。