高性能“适当”的 C++ 替代可变长度数组

Ebo*_*ers 8 c++ arrays compiler-explorer

我正在编写一个需要在运行时创建数组的函数。该数组将是小尺寸,因此我不担心不安全的代码,但是,我想编写“正确”的代码。因此,我正在考虑三种选择:

  1. 字符数组[len];
  2. 字符数组 = 新字符(len);
  3. std::vector 数组(len);

使用Compiler Explorer将它们与 -O3 进行比较。结果如下:

  1. 12条指令,0次调用new
  2. 21条指令,1次调用new
  3. 118 条指令,2+ 次调用 new

我是否错过了对 std::vector<> 的优化,或者“正确的”C++ 方式是否较慢,或者我完全错过了一种编码方式?

编辑:我忘了删除堆分配的数组

测试代码:

代码1:

#include <string.h>

void populate_array(char* arr);
int compute_result(char* arr);

int str_to_arr(const char* str)
{
    auto len = strlen(str);
    char array[len];
    populate_array(array);
    return compute_result(array);
}
Run Code Online (Sandbox Code Playgroud)

代码2:

#include <string.h>

void populate_array(char* arr);
int compute_result(char* arr);

int str_to_arr(const char* str)
{
    auto len = strlen(str);
    char* array = new char[len];
    populate_array(array);
    auto result = compute_result(array);
    delete[] array;
    return result;
}
Run Code Online (Sandbox Code Playgroud)

代码3:

#include <string.h>
#include <vector>

void populate_array(std::vector<char> arr);
int compute_result(std::vector<char> arr);

int str_to_arr(const char* str)
{
    auto len = strlen(str);
    std::vector<char> array(len);
    populate_array(array);
    return compute_result(array);
}
Run Code Online (Sandbox Code Playgroud)

hal*_*lat 7

代码中存在一些问题,可能会导致您在比较中误入歧途。

  1. new char(len)分配单个字符,用 value 初始化len。你会在new char[len]分配len字符之后。也应该有一个匹配delete []
  2. std::vector<char>对象populate_array按值传递,制作一个副本(因此实际上不会填充您想要的数组),对于compute_result. 这些副本将产生新的分配。在这里通过引用传递是合适的。
  3. 不使用自定义分配器,std::vector将对所有元素进行值初始化。实际上,这意味着该向量中的每个元素都设置为零。这不是由 执行的new char[len]

VLA 不是 C++ 的一部分,但可以作为扩展提供。虽然在这种情况下,对于 small len,编译器可以选择为堆栈上的数组分配空间,但由于它们的非标准性质,最好避免使用它们;即使在 C 中,也不需要支持它们。

  • 添加到此注释中,考虑使用 `std::vector&lt;char&gt; array; array.reserve(len);` 然后稍后使用 `array.push_back(something)`。 (2认同)