unsigned char
null ターミネータのないさまざまな固定サイズの配列を文字列として使用する C ライブラリを使用しています。
私は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 配列のサイズを追跡する必要がなく、他のすべてがより簡単になります。しかし、いくつかのベンチマーク ( nanobenchreinterpret_cast
を使用) でさらに掘り下げると、新しい関数は従来の方法よりも何倍も遅いことがわかります。私の仮定は、ベース関数のfor
ループがここで非効率的であるということです。std::span
私の質問:std::span
unsigned char の固定サイズの C 配列を変数からに変換するより効率的な方法はありstd::string
ますか?
編集:
gcc
ベンチマーク (-O3 -DNDEBUG -std=gnu++20、ナノベンチ、minEpochIterations=54552558、ウォームアップ=100、doNotOptimizeAway)
相対的 | ns/op | オペレーション | エラー% | イン/オペレーション | ブラ/手術 | お嬢% | 合計 | 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、ナノベンチ、minEpochIterations=54552558、ウォームアップ=100、doNotOptimizeAway)
相対的 | ns/op | オペレーション | エラー% | イン/オペレーション | ブラ/手術 | お嬢% | 合計 | 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>