如果我想构建一个非常简单的数组,比如:
int myArray[3] = {1,2,3};
我应该使用 std::array代替吗?
std::array
std::array<int, 3> a = {{1, 2, 3}};
使用 std::array的优点是什么? 它的性能更好吗? 只是更容易处理复制/访问?
std::array被设计为 C 数组的零开销包装器,它提供了类似于其他 C + + 容器语义的“普通”值。
在享受额外特性的同时,您不应该注意到运行时性能的任何差异。
使用 std::array而不是 int[]样式数组是一个好主意,如果你有 C + + 11或增强手头。
int[]
使用 std::array的优点是什么?
它具有友好的值语义,因此它可以通过值传递给函数或从函数返回。它的接口使得查找大小更加方便,并且可以与 STL 风格的基于迭代器的算法一起使用。
更有表现力吗?
它应该是完全相同的。根据定义,它是一个包含数组作为其唯一成员的简单聚合。
只是更容易处理复制/访问?
是的。
std::array具有值语义,而原始数组没有。这意味着您可以复制 std::array并将其视为一个基元值。可以通过值或作为函数参数的引用接收它们,也可以通过值返回它们。
如果您从未复制过 std::array,那么与原始数组相比就没有性能差异。如果你确实需要复制,那么 std::array会做正确的事情,仍然应该给予相同的性能。
std::array是围绕 C 样式数组的一个非常薄的包装器,基本上定义为
template<typename T, size_t N> struct array { T _data[N]; T& operator[](size_t); const T& operator[](size_t) const; // other member functions and typedefs };
它是一个 总和,它允许您像使用基本类型一样使用它(例如,您可以通过值传递、赋值等,而标准的 C 数组不能直接赋值或复制到另一个数组)。你应该看看一些标准的实现(从你喜欢的 IDE 跳转到定义,或者直接打开 <array>) ,这是一个非常容易阅读和理解的 C++标准程式库。
<array>
更有表现力吗? 它应该是完全相同的。根据定义,它是一个包含数组作为其唯一成员的简单聚合。
情况似乎更加复杂,因为取决于特定的平台,与 C-array 相比,std::array并不总是产生相同的汇编代码。
我在 Godbolt上测试了这个具体情况:
#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 和 当为 C 阵列版本和 std::array版本生成相同的汇编代码。
然而,MSVC 和 ICPC为每个数组版本生成不同的汇编代码。(我用 -Ofast和 -Os; MSVC -Ox和 -Os测试 ICPC19)
-Ofast
-Os
-Ox
我不知道为什么会这样(我的确希望 std: : array 和 c-array 的行为完全相同)。也许存在不同的优化策略。
作为小小的额外补充: ICPC 似乎有一个漏洞
#pragma simd
在某些情况下使用 c 数组进行向量化 (c-array 代码产生错误的输出; std::array版本工作正常)。
不幸的是,我还没有一个最小的工作示例来解决这个问题,因为我是在优化一段相当复杂的代码时发现这个问题的。
当我确定我没有误解关于 C-array/std::array和 #pragma simd的一些东西时,我会向英特尔提交一份错误报告。
您将使用 std::array和 c array获得相同的性能结果 如果运行以下代码:
c array
std::array<QPair<int, int>, 9> *m_array=new std::array<QPair<int, int>, 9>(); QPair<int, int> *carr=new QPair<int, int>[10]; QElapsedTimer timer; timer.start(); for (int j=0; j<1000000000; j++) { for (int i=0; i<9; i++) { m_array->operator[](i).first=i+j; m_array->operator[](i).second=j-i; } } qDebug() << "std::array<QPair<int, int>" << timer.elapsed() << "milliseconds"; timer.start(); for (int j=0; j<1000000000; j++) { for (int i=0; i<9; i++) { carr[i].first=i+j; carr[i].second=j-i; } } qDebug() << "QPair<int, int> took" << timer.elapsed() << "milliseconds"; return 0;
你会得到以下结果:
std::array<QPair<int, int> 5670 milliseconds QPair<int, int> took 5638 milliseconds
Mike Seymour 是对的,如果你能使用 std::array,你就应该使用它。