c++ std::move_iterator

epggiuax  于 2023-05-08  发布在  其他
关注(0)|答案(7)|浏览(331)

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

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

应该使用std::array吗?

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

使用std::array比使用普通的std::array有什么优势?它的性能更高吗?只是更容易处理复制/访问?

kx7yvsdv

kx7yvsdv1#

使用std::array比普通的有什么优势?
它具有友好的值语义,因此它可以通过值传递给函数或从函数返回。它的接口使它更方便地找到大小,并与STL风格的基于迭代器的算法一起使用。
它的性能更高吗?
应该是一模一样的。根据定义,它是一个简单的聚合,包含一个数组作为其唯一的成员。
只是更容易处理复制/访问?
是的。

qojgxg4l

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++标准库,非常容易阅读和理解。

yhxst69z

yhxst69z3#

std::array被设计为C数组的零开销 Package 器,它赋予它“正常”值,就像其他C容器的语义一样。
您应该不会注意到运行时性能的任何差异,同时您仍然可以享受额外的功能。
使用std::array而不是int[]风格的数组是一个好主意,如果你手头有C
11或boost。

dvtswwa3

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];
  }
}

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

但是,MSVCICPC为每个阵列版本生成不同的汇编代码。(我用-Ofast-Os测试了ICPC 19; MSVC -Ox-Os
我不知道为什么会这样(我确实希望std::array和c-array的行为完全相同)。可能采用不同的优化策略。
作为一个小额外:在ICPC中似乎有一个bug

#pragma simd

用于在某些情况下使用c数组时的向量化(c数组代码产生错误的输出; std::array版本工作正常)。
不幸的是,我还没有一个最小的工作示例,因为我在优化一段相当复杂的代码时发现了这个问题。
当我确信我没有误解C-array/std::array#pragma simd的某些内容时,我会向英特尔提交一份错误报告。

70gysomp

70gysomp5#

std::array具有值语义,而原始数组没有。这意味着您可以复制std::array并将其视为原始值。您可以通过值或引用作为函数参数接收它们,并且可以通过值返回它们。
如果您从不复制std::array,则与原始阵列相比没有性能差异。如果您确实需要制作副本,那么std::array将做正确的事情,并且仍然可以给予相同的性能。

enyaitl3

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,你应该使用它。

gk7wooem

gk7wooem7#

虽然std::array有一些优点,正如其他答案中所概述的那样,有些人说,“...与原始阵列相比没有性能差异。”
这根本不是真的,并且会误导任何从事真正嵌入式开发(时间关键型,裸机)的人。
使用STM32G0B1在50MHz(CPU)下运行的快速脏测试:写入std::array比写入原始C风格数组大约多5 µS。对我来说,这是一个不容忽视的显著性能差异。

相关问题