高性能 'proper' c++ 替代可变长度数组
high performance 'proper' c++ alternative to variable length array
我正在编写一个需要在运行时创建数组的函数。该数组将很小,所以我不担心不安全的代码,但是,我想编写 'proper' 代码。因此,我正在考虑三种选择:
- 字符数组[len];
- char array = new char(len);
- std::vector 数组(len);
使用Compiler Explorer 将它们与-O3 进行比较。
结果是这样的:
- 12 条指令,0 次调用 new
- 21 条指令,1 次调用 new
- 118 条指令,2 次以上调用 new
我是否错过了对 std::vector<> 的优化,或者 'proper' 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);
}
代码中存在一些问题,可能会导致您在比较中误入歧途。
new char(len)
分配单个字符,用值 len
初始化。您会在 new char[len]
之后分配 len
个字符。也应该有匹配的delete []
。
std::vector<char>
对象按值传递给 populate_array
,制作一个副本(因此不会实际填充您想要的数组),对于 compute_result
也是如此。这些副本将产生新的分配。通过引用传递在这里是合适的。
- 不使用自定义分配器,
std::vector
将对其所有元素进行值初始化。实际上,这意味着该向量中的每个元素都设置为零。这不是由 new char[len]
. 执行的
VLA 不是 C++ 的一部分,但可以作为扩展提供。虽然在这种情况下,对于小 len
,编译器可以选择为堆栈上的数组分配 space,但由于它们的非标准性质,最好避免使用它们;即使在 C 中,也不需要支持它们。
我正在编写一个需要在运行时创建数组的函数。该数组将很小,所以我不担心不安全的代码,但是,我想编写 'proper' 代码。因此,我正在考虑三种选择:
- 字符数组[len];
- char array = new char(len);
- std::vector 数组(len);
使用Compiler Explorer 将它们与-O3 进行比较。 结果是这样的:
- 12 条指令,0 次调用 new
- 21 条指令,1 次调用 new
- 118 条指令,2 次以上调用 new
我是否错过了对 std::vector<> 的优化,或者 'proper' 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);
}
代码中存在一些问题,可能会导致您在比较中误入歧途。
new char(len)
分配单个字符,用值len
初始化。您会在new char[len]
之后分配len
个字符。也应该有匹配的delete []
。std::vector<char>
对象按值传递给populate_array
,制作一个副本(因此不会实际填充您想要的数组),对于compute_result
也是如此。这些副本将产生新的分配。通过引用传递在这里是合适的。- 不使用自定义分配器,
std::vector
将对其所有元素进行值初始化。实际上,这意味着该向量中的每个元素都设置为零。这不是由new char[len]
. 执行的
VLA 不是 C++ 的一部分,但可以作为扩展提供。虽然在这种情况下,对于小 len
,编译器可以选择为堆栈上的数组分配 space,但由于它们的非标准性质,最好避免使用它们;即使在 C 中,也不需要支持它们。