向量与动态数组基准 - 什么是瓶颈?

时间:2018-05-15 21:23:03

标签: c++ vector stl benchmarking

鼓励在动态阵列上使用STL,但我很好奇可能是什么瓶颈? MAX_PACKET_LENGTH32768

---------------------------------------------------------------------------
Benchmark                                    Time           CPU Iterations
---------------------------------------------------------------------------
BM_VectorInit                             1335 ns       1193 ns     497778
BM_RawInit                                  58 ns         55 ns   10000000


static void BM_VectorInit(benchmark::State &state)
{
    for (auto _ : state) 
    {
        std::vector<char> a(MAX_PACKET_LENGTH);
    }
}

static void BM_RawInit(benchmark::State &state)
{
    for (auto _ : state) 
    {
        auto a = new char[MAX_PACKET_LENGTH];
        delete[] a;
    }
}

2 个答案:

答案 0 :(得分:4)

首先,正如@juanchopanza所建议的那样 - 如果你没有提供适当的测试程序,我们就无法重现你的数字;你刚刚给了我们两个什么都不做的功能,并且不会在二进制文件中产生任何结果。

无论如何,似乎开销是由于std::vector零初始化char值。

如果您想避免发生这种情况,或者只是为了进行基准测试的公平竞争,请使用a struct which wraps a char and doesn't initialize it作为向量元素类型,然后再次运行测试。我不建议在生产代码中实际使用这样一个愚蠢的结构 - 使用你真正需要的类型。

谈到使用你需要的东西 - 它完全可以使用:

auto buffer_ptr = std::make_unique<char[]>(MAX_PACKET_LENGTH);

然后可能:

auto buffer = std::span<char>(raw_buffer.get(), MAX_PACKET_LENGTH);

您几乎可以在任何地方使用spans std::vector。 (请注意,std::span仅出现在C ++ 20中,现在您需要GSL实现。)

答案 1 :(得分:-1)

您正在比较构造std::vector的成本与在堆上分配数组的成本。当你创建一个std::vector时,它会在堆内部分配一个数组,但是还有额外的开销,因为std::vector本身就是一个需要构造和存储的对象(可能在堆栈上或者在堆)。因此,创建std::vector所需的时间比创建new char[]所需的时间更长。

话虽如此,BM_RawInitBM_VectorInit之间还有另一个区别。当您使用一个整数参数构造std::vector时,就像在std::vector<char> a(MAX_PACKET_LENGTH)中一样,会发生两件事。将在MAX_PACKET_LENGTH的堆上分配空间,这些项也将默认构建。另一方面,执行new char[MAX_PACKET_LENGTH]时,只会进行分配。

为了更好的比较,尝试创建仅分配空间的第三个基准,如下所示:

static void BM_VectorReserve(benchmark::State &state)
{
    for (auto _ : state) 
    {
        std::vector<char> a;
        a.reserve(MAX_PACKET_LENGTH);
    }
}

这不是完美的比较,因为在我们声明a的第一行会分配少量内存,然后当我们调用reserve时,那个初始内存将会被释放。之后,std::vector将为MAX_PACKET_LENGTH项目分配足够的空间。在实际代码中,这通常可以忽略不计,但为了您的基准,它可以部分解释为什么BM_VectorReserve需要的时间超过BM_RawInit

相关问题