3

次のように、boost::variantを使用してdoubleまたはstringを格納するクラスがあります。

class value
{
  boost::variant<double, std::string> val;
};

これは、私が遊んでいるおもちゃのインタプリタにとっては不変の値型であると考えられています。最初は、const参照で渡し、値で返すことをお勧めします。プリミティブとして扱いたいので、常にスタックに割り当てます。しかし、サイズが40バイトであることがわかり(ほとんどの場合、sizeof std :: stringが原因です)、少し心配でした。スタックに大きなメモリチャンクを割り当てるべきではないことはわかっていますが、大きすぎるのはどれくらいですか?

また、戻るたびに40バイトをコピーすることは、特に値が不変であり、コピーする必要さえないため、少し無駄に思えます。

オプションの通常のヒープ割り当ては、1秒あたり数千のこれらの割り当て/割り当て解除を行うことができるため、あまり魅力的ではないようです。

私が思いついた最後のオプションは、必要に応じてこれらのオブジェクトを割り当てるためにboost :: poolを用意し、それらの存続期間を管理するためにboost::shared_ptrを使用することです。ただし、インタプリタがメモリ割り当てを担当するため(メモリ割り当てのタイプは、テンプレート引数としてインタプリタに渡されるポリシーになります)、これは、値クラスがインタプリタについて知る必要があることを意味し、少し複雑になります。 。

だからこれらは質問です:

  • この場合、どうすればよいですか、またその理由は何ですか?
  • スタックに割り当てるには「大きすぎる」の大きさはどれくらいですか?それは、割り当てられる頻度とコピーする必要がある頻度にもよると思います。

ありがとう。

4

2 に答える 2

4
  • この場合、どうすればよいですか、またその理由は何ですか?

いつものように、最も理解しやすいようにプログラムを書いてください。後でプロファイリングによってこれが実際に問題であることが判明した場合は、後で動的に割り当てられたオブジェクトにいつでも変換できますvalue::val。(もちろん、これはval、クラスのクライアントに影響を与えないように十分に抽象化されていることを前提としています。)

  • スタックに割り当てるには「大きすぎる」の大きさはどれくらいですか?それは、それが割り当てられる頻度と、コピーする必要がある頻度にも依存すると確信しています。

また、使用しているプラ​​ットフォームによっても異なります。トースターまたは64ビットワークステーションを実行する8ビット組み込みチップについて話しているのですか?
結局のところ、IMOは次のように要約されます。サイズが原因で問題が発生する場合は、大きすぎます。

于 2011-06-07T13:14:51.247 に答える
0

これを本当に最適化する必要がある場合はstd::string、Windowsでは使用しないことをお勧めします。

不変の文字列の場合、コピーオンライトのような実装(基本的に、文字列のすべてのコピーが同じ内部バッファを共有します)を。の上に簡単に実装できますshared_ptr

それ以降、クラスに必要なポインタは1つだけなので、ConstStringコピーを渡すことを心配する必要はありません。

于 2011-06-07T13:28:15.397 に答える