鼓励在动态阵列上使用STL,但我很好奇可能是什么瓶颈? MAX_PACKET_LENGTH
为32768
。
---------------------------------------------------------------------------
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;
}
}
答案 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_RawInit
和BM_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
。