【问题标题】:high performance 'proper' c++ alternative to variable length array可变长度数组的高性能“正确”C++ 替代方案
【发布时间】:2021-01-10 11:26:12
【问题描述】:

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

  1. 字符数组[len];
  2. char 数组 = new char(len);
  3. std::vector array(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);
}

代码 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;
}

代码 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);
}

【问题讨论】:

  • 向量代码也释放了其他代码不做的内存。
  • 还有unique_ptr
  • 代码 1 不适合我,也不应该编译。您作为数组大小传递的值必须是 constexpr,但这里显然不是。
  • 另外std::vector test case 应该只分配 1 个堆,除非有我们没有看到的代码会增加它的大小。
  • 这里有几个选项:godbolt.org/z/Gv1oGM。代码中的一些错误:向量一个复制整个向量,因为您通过值传递与其他向量不具有可比性(通过引用传递或传递data() 指针)。您应该使用new char[len] 分配len 字节的字符。代码 2 中存在内存泄漏,因为您没有 delete[] array

标签: c++ arrays compiler-explorer


【解决方案1】:

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

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

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

【讨论】:

  • 添加到此评论,考虑使用std::vector&lt;char&gt; array; array.reserve(len); 然后稍后使用array.push_back(something)
猜你喜欢
  • 2012-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-24
  • 1970-01-01
相关资源
最近更新 更多