4

アプリケーションのプロファイリングにより、CPU 時間の 5% 近くを文字列の割り当てに費やしていることがわかりました。多くの場所で、64MB の char バッファから C++ std::string オブジェクトを作成しています。問題は、プログラムの実行中にバッファが変更されることはありません。呼び出しの私の分析はstd::string(const char *buf,size_t buflen)、文字列が作成された後にバッファが変更される可能性があるため、文字列がコピーされているということです。それはここの問題ではありません。この問題を回避する方法はありますか?

EDIT:私はバイナリデータを扱っているので、単に渡すことはできませんchar *s. さらに、常に NULL をスキャンすることでかなりのオーバーヘッドが発生しますが、これはstd::string回避できます。

4

5 に答える 5

7

文字列が変更されず、文字列を使用するよりも寿命が長くなることが保証されている場合は、使用しないでくださいstd::string

代わりに、提案された のような単純な C 文字列ラッパーを検討してstring_ref<T>ください。

于 2012-10-08T16:40:07.733 に答える
4

バイナリデータ?std::string の使用をやめて、 を使用してstd::vector<char>ください。しかし、それでコピーされるという問題は解決しません。あなたの説明から、この巨大な 64MB バッファが変更されない場合、本当に std::string または を使用するべきではありませんstd::vector<char>。どちらも良い考えではありません。本当に const char* ポインターを渡す必要があります (const uint8_t* はバイナリ データをより説明しますが、内部では同じことであり、符号の問題は無視されます)。ポインターとその size_t の長さの両方を渡すか、別の「終了」ポインターを使用してポインターを渡します。個別の離散変数 (ポインターとバッファーの長さ) を渡したくない場合は、バッファーを記述する構造体を作成し、代わりに全員にそれらを使用してもらいます。

struct binbuf_desc {
    uint8_t* addr;
    size_t len;
    binbuf_desc(addr,len) : addr(addr), len(len) {}
}

オブジェクトを使用して、いつでも 64MB バッファー (または任意のサイズの他のバッファー) を参照できbinbuf_descます。binbuf_desc オブジェクトはバッファー (またはそのコピー) を所有していないことに注意してください。それらは単なる記述子であるため、binbuf_desc がバッファーの不要なコピーを作成することを心配することなく、それらをどこにでも渡すことができます。

于 2012-10-09T15:29:48.477 に答える
3

移植可能なソリューションはありません。使用しているツールチェーンを教えていただければ、ライブラリの実装に固有のトリックを知っている人がいるかもしれません。しかし、ほとんどの場合、std::stringデストラクタ (および代入演算子) は文字列の内容を解放しようとしており、文字列リテラルを解放することはできません。(これに例外を設けることは不可能ではありません。実際、小さな文字列の最適化は割り当て解除をスキップする一般的なケースですが、これらは実装の詳細です。)

より良いアプローチは、std::string動的割り当てを必要としない/したくない場合は使用しないことです。 const char*最新の C++ でも問題なく動作します。

于 2012-10-08T16:38:40.767 に答える
0

const char *の代わりに使用するのstd::stringが最善の方法のようです。ただし、文字列の使用方法も考慮する必要があります。std::stringchar ポインターからオブジェクトへの暗黙的な変換が行われている可能性があります。これは、たとえば、関数呼び出し中に発生する可能性があります。

于 2012-10-08T16:47:36.490 に答える