std::array 对比阵列性能
std::array vs array performance
如果我想构建一个非常简单的数组,例如:
int myArray[3] = {1,2,3};
我应该改用 std::array
吗?
std::array<int, 3> a = {{1, 2, 3}};
使用 std::array
与通常的相比有什么优势?它的性能更高吗? copy/access?
更容易处理
std::array
被设计为 C 数组的零开销包装器,赋予它 "normal" 值,就像其他 C++ 容器的语义一样。
您应该不会注意到运行时性能有任何差异,同时您仍然可以享受额外的功能。
如果手头有 C++11 或 boost,使用 std::array
而不是 int[]
样式数组是个好主意。
What are the advantages of using std::array
over usual ones?
它具有友好的值语义,因此可以按值传递给函数或从函数返回。它的界面使得查找大小和与基于 STL 样式迭代器的算法一起使用更加方便。
Is it more performant ?
应该是一模一样的。根据定义,它是一个包含数组作为其唯一成员的简单聚合。
Just easier to handle for copy/access ?
是的。
std::array
具有值语义,而原始数组则没有。这意味着您可以复制 std::array
并将其视为原始值。您可以按值或引用作为函数参数接收它们,并且可以 return 按值接收它们。
如果您从不复制 std::array
,那么与原始数组没有性能差异。如果您确实需要制作副本,那么 std::array
会做正确的事情并且应该仍然提供同等的性能。
A 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
};
它是一个 aggregate,它允许您几乎像基本类型一样使用它(即您可以按值传递、赋值等,而标准 C 数组不能直接赋值或复制到另一个数组)。你应该看看一些标准实现(从你喜欢的IDE跳转到定义或直接打开<array>
),它是C++标准库的一部分,非常容易阅读和理解。
Is it more performant ?
It should be exactly the same. By definition, it's a simple aggregate containing an array as its only member.
The situation seems to be more complicated, as std::array
does not always produce identical assembly code compared to C-array depending on the specific platform.
I tested this specific situation on 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 and Clang produce identical assembly code for both the C-array version and the std::array
version.
MSVC and ICPC, however, produce different assembly code for each array version. (I tested ICPC19 with -Ofast
and -Os
; MSVC -Ox
and -Os
)
I have no idea, why this is the case (I would indeed expect exactly identical behavior of std::array and c-array). Maybe there are different optimization strategies employed.
As a little extra:
There seems to be a bug in ICPC with
#pragma simd
for vectorization when using the c-array in some situations
(the c-array code produces a wrong output; the std::array
version works fine).
Unfortunately, I do not have a minimal working example for that yet, since I discovered that problem while optimizing a quite complicated piece of code.
I will file a bug-report to intel when I am sure that I did not just misunderstood something about C-array/std::array
and #pragma simd
.
您将使用 std::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
你应该使用它。
如果我想构建一个非常简单的数组,例如:
int myArray[3] = {1,2,3};
我应该改用 std::array
吗?
std::array<int, 3> a = {{1, 2, 3}};
使用 std::array
与通常的相比有什么优势?它的性能更高吗? copy/access?
std::array
被设计为 C 数组的零开销包装器,赋予它 "normal" 值,就像其他 C++ 容器的语义一样。
您应该不会注意到运行时性能有任何差异,同时您仍然可以享受额外的功能。
如果手头有 C++11 或 boost,使用 std::array
而不是 int[]
样式数组是个好主意。
What are the advantages of using
std::array
over usual ones?
它具有友好的值语义,因此可以按值传递给函数或从函数返回。它的界面使得查找大小和与基于 STL 样式迭代器的算法一起使用更加方便。
Is it more performant ?
应该是一模一样的。根据定义,它是一个包含数组作为其唯一成员的简单聚合。
Just easier to handle for copy/access ?
是的。
std::array
具有值语义,而原始数组则没有。这意味着您可以复制 std::array
并将其视为原始值。您可以按值或引用作为函数参数接收它们,并且可以 return 按值接收它们。
如果您从不复制 std::array
,那么与原始数组没有性能差异。如果您确实需要制作副本,那么 std::array
会做正确的事情并且应该仍然提供同等的性能。
A 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
};
它是一个 aggregate,它允许您几乎像基本类型一样使用它(即您可以按值传递、赋值等,而标准 C 数组不能直接赋值或复制到另一个数组)。你应该看看一些标准实现(从你喜欢的IDE跳转到定义或直接打开<array>
),它是C++标准库的一部分,非常容易阅读和理解。
Is it more performant ?
It should be exactly the same. By definition, it's a simple aggregate containing an array as its only member.
The situation seems to be more complicated, as std::array
does not always produce identical assembly code compared to C-array depending on the specific platform.
I tested this specific situation on 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 and Clang produce identical assembly code for both the C-array version and the std::array
version.
MSVC and ICPC, however, produce different assembly code for each array version. (I tested ICPC19 with -Ofast
and -Os
; MSVC -Ox
and -Os
)
I have no idea, why this is the case (I would indeed expect exactly identical behavior of std::array and c-array). Maybe there are different optimization strategies employed.
As a little extra: There seems to be a bug in ICPC with
#pragma simd
for vectorization when using the c-array in some situations
(the c-array code produces a wrong output; the std::array
version works fine).
Unfortunately, I do not have a minimal working example for that yet, since I discovered that problem while optimizing a quite complicated piece of code.
I will file a bug-report to intel when I am sure that I did not just misunderstood something about C-array/std::array
and #pragma simd
.
您将使用 std::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
你应该使用它。