我将使用中文进行翻译,以下是您需要翻译的内容:
该函数很好用,无需跟踪C数组的大小即可简化其他所有操作。但是,进一步深入研究并进行基准测试(使用nanobench)表明,新函数比经典的
我的问题是:是否有更有效的方法将
在基准测试中,
我正在使用一个C库,该库使用各种固定大小的unsigned char
数组作为字符串,没有空终止符。
我一直在使用以下函数将它们转换为std::string
:
auto uchar_to_stdstring(const unsigned char* input_array, int width) -> std::string {
std::string temp_string(reinterpret_cast<const char*>(input_array), width);
temp_string.erase(temp_string.find_last_not_of(' ') + 1);
return temp_string;
}
除了使用reinterpret_cast
、需要传递数组大小以及将数组降级为指针之外,一切正常。我试图使用std::span
来避免所有这些问题。
使用std::span
的函数如下:
auto ucharspan_to_stdstring(const std::span<unsigned char>& input_array) -> std::string {
std::stringstream temp_ss;
for (const auto& input_arr_char : input_array) {
temp_ss << input_arr_char;
}
return temp_ss.str();
}
该函数很好用,无需跟踪C数组的大小即可简化其他所有操作。但是,进一步深入研究并进行基准测试(使用nanobench)表明,新函数比经典的
reinterpret_cast
方法慢得多。我的假设是std::span
函数中的for
循环是这里的低效率原因。我的问题是:是否有更有效的方法将
std::span
变量中的固定大小的C数组转换为std::string
?
编辑:
gcc
基准测试 (-O3 -DNDEBUG -std=gnu++20,nanobench,minEpochIterations=54552558,热身=100,不要优化掉)
相对值 | ns/操作 | 操作数/秒 | 错误率% | 每操作插入字节数 | 分支预测错误次数/操作 | 缺失率% | 总计 | uchar[] 转 std::string |
---|---|---|---|---|---|---|---|---|
100.0% | 5.39 | 185,410,438.12 | 0.3% | 80.00 | 20.00 | 0.0% | 3.56 | uchar |
2.1% | 253.06 | 3,951,678.30 | 0.6% | 4,445.00 | 768.00 | 0.0% | 167.74 | ucharspan |
1,244.0% | 0.43 | 2,306,562,499.69 | 0.2% | 9.00 | 1.00 | 0.0% | 0.29 | ucharspan_barry |
72.8% | 7.41 | 134,914,127.56 | 1.3% | 99.00 | 22.00 | 0.0% | 4.89 | uchar_bsv |
clang
基准测试 (-O3 -DNDEBUG -std=gnu++20, nanobench, minEpochIterations=54552558, warmup=100, doNotOptimizeAway)
相对值 | 纳秒/操作 | 操作数/秒 | 错误率% | 每个操作的指令数 | 每个分支数 | 缺失率% | 总计 | uchar[] 转为 std::string |
---|---|---|---|---|---|---|---|---|
100.0% | 2.13 | 468,495,014.11 | 0.2% | 14.00 | 1.00 | 0.0% | 1.42 | uchar |
0.8% | 251.74 | 3,972,418.54 | 0.2% | 4,477.00 | 767.00 | 0.0% | 166.30 | ucharspan |
144.4% | 1.48 | 676,329,668.07 | 0.1% | 7.00 | 0.00 | 95.8% | 0.98 | ucharspan_barry |
34.5% | 6.19 | 161,592,563.70 | 0.1% | 80.00 | 24.00 | 0.0% | 4.08 | uchar_bsv |
uchar_bsv
与ucharspan_barry
相同,但使用的参数是std::basic_string_view<unsigned char const>
而不是std::span<unsigned char const>
。
erase
? - Barrystring_view
是有符号字符吗?不,它是char
。但这并不是我想说的重点。实际上我指的是basic_string_view
,它是一个模板。你可以直接使用std::basic_string_view<unsigned char>
。 - eerorika