如果我想构建一个非常简单的数组:
int myArray[3] = {1,2,3};
应该使用std::array吗?
std::array
std::array<int, 3> a = {{1, 2, 3}};
使用std::array比使用普通的std::array有什么优势?它的性能更高吗?只是更容易处理复制/访问?
kx7yvsdv1#
使用std::array比普通的有什么优势?它具有友好的值语义,因此它可以通过值传递给函数或从函数返回。它的接口使它更方便地找到大小,并与STL风格的基于迭代器的算法一起使用。它的性能更高吗?应该是一模一样的。根据定义,它是一个简单的聚合,包含一个数组作为其唯一的成员。只是更容易处理复制/访问?是的。
qojgxg4l2#
std::array是C风格数组的一个非常薄的 Package 器,基本上定义为
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++标准库,非常容易阅读和理解。
<array>
yhxst69z3#
std::array被设计为C数组的零开销 Package 器,它赋予它“正常”值,就像其他C容器的语义一样。您应该不会注意到运行时性能的任何差异,同时您仍然可以享受额外的功能。使用std::array而不是int[]风格的数组是一个好主意,如果你手头有C11或boost。
int[]
dvtswwa34#
它的性能更高吗?应该是一模一样的。根据定义,它是一个简单的聚合,包含一个数组作为其唯一的成员。情况似乎更复杂,因为std::array并不总是产生与C-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和Clang为C-array版本和std::array版本生成相同的汇编代码。
但是,MSVC和ICPC为每个阵列版本生成不同的汇编代码。(我用-Ofast和-Os测试了ICPC 19; MSVC -Ox和-Os)我不知道为什么会这样(我确实希望std::array和c-array的行为完全相同)。可能采用不同的优化策略。作为一个小额外:在ICPC中似乎有一个bug
-Ofast
-Os
-Ox
#pragma simd
用于在某些情况下使用c数组时的向量化(c数组代码产生错误的输出; std::array版本工作正常)。不幸的是,我还没有一个最小的工作示例,因为我在优化一段相当复杂的代码时发现了这个问题。当我确信我没有误解C-array/std::array和#pragma simd的某些内容时,我会向英特尔提交一份错误报告。
70gysomp5#
std::array具有值语义,而原始数组没有。这意味着您可以复制std::array并将其视为原始值。您可以通过值或引用作为函数参数接收它们,并且可以通过值返回它们。如果您从不复制std::array,则与原始阵列相比没有性能差异。如果您确实需要制作副本,那么std::array将做正确的事情,并且仍然可以给予相同的性能。
enyaitl36#
如果你运行下面的代码,你将得到相同的性能结果:
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,你应该使用它。
gk7wooem7#
虽然std::array有一些优点,正如其他答案中所概述的那样,有些人说,“...与原始阵列相比没有性能差异。”这根本不是真的,并且会误导任何从事真正嵌入式开发(时间关键型,裸机)的人。使用STM32G0B1在50MHz(CPU)下运行的快速脏测试:写入std::array比写入原始C风格数组大约多5 µS。对我来说,这是一个不容忽视的显著性能差异。
7条答案
按热度按时间kx7yvsdv1#
使用
std::array
比普通的有什么优势?它具有友好的值语义,因此它可以通过值传递给函数或从函数返回。它的接口使它更方便地找到大小,并与STL风格的基于迭代器的算法一起使用。
它的性能更高吗?
应该是一模一样的。根据定义,它是一个简单的聚合,包含一个数组作为其唯一的成员。
只是更容易处理复制/访问?
是的。
qojgxg4l2#
std::array
是C风格数组的一个非常薄的 Package 器,基本上定义为它是一个aggregate,它允许你像使用基本类型一样使用它(即你可以通过值传递,赋值等,而一个标准的C数组不能直接赋值或复制到另一个数组)。你应该看看一些标准的实现(从你喜欢的IDE跳转到定义或直接打开
<array>
),它是一个C++标准库,非常容易阅读和理解。yhxst69z3#
std::array
被设计为C数组的零开销 Package 器,它赋予它“正常”值,就像其他C容器的语义一样。您应该不会注意到运行时性能的任何差异,同时您仍然可以享受额外的功能。
使用
std::array
而不是int[]
风格的数组是一个好主意,如果你手头有C11或boost。dvtswwa34#
它的性能更高吗?
应该是一模一样的。根据定义,它是一个简单的聚合,包含一个数组作为其唯一的成员。
情况似乎更复杂,因为
std::array
并不总是产生与C-array相同的汇编代码,这取决于特定的平台。我在godbolt上测试了这个特定的情况:
GCC和Clang为C-array版本和
std::array
版本生成相同的汇编代码。但是,MSVC和ICPC为每个阵列版本生成不同的汇编代码。(我用
-Ofast
和-Os
测试了ICPC 19; MSVC-Ox
和-Os
)我不知道为什么会这样(我确实希望std::array和c-array的行为完全相同)。可能采用不同的优化策略。
作为一个小额外:在ICPC中似乎有一个bug
用于在某些情况下使用c数组时的向量化(c数组代码产生错误的输出;
std::array
版本工作正常)。不幸的是,我还没有一个最小的工作示例,因为我在优化一段相当复杂的代码时发现了这个问题。
当我确信我没有误解C-array/
std::array
和#pragma simd
的某些内容时,我会向英特尔提交一份错误报告。70gysomp5#
std::array
具有值语义,而原始数组没有。这意味着您可以复制std::array
并将其视为原始值。您可以通过值或引用作为函数参数接收它们,并且可以通过值返回它们。如果您从不复制
std::array
,则与原始阵列相比没有性能差异。如果您确实需要制作副本,那么std::array
将做正确的事情,并且仍然可以给予相同的性能。enyaitl36#
如果你运行下面的代码,你将得到相同的性能结果:
你会得到这些结果:
Mike Seymour是对的,如果你可以使用
std::array
,你应该使用它。gk7wooem7#
虽然
std::array
有一些优点,正如其他答案中所概述的那样,有些人说,“...与原始阵列相比没有性能差异。”这根本不是真的,并且会误导任何从事真正嵌入式开发(时间关键型,裸机)的人。
使用STM32G0B1在50MHz(CPU)下运行的快速脏测试:写入
std::array
比写入原始C风格数组大约多5 µS。对我来说,这是一个不容忽视的显著性能差异。