0

ほとんどが C++ で開発されたアプリケーションのメモリ フットプリントを削減しようとしています。私が調べていたのは、特に大きなデータ構造を参照で返すのではなく、値で返すことでした。私はそれについていくつかの確認が必要でした。たとえば、クラスsome_objectに次のようなメンバー関数があるとします。

const some_type& get_some_type(...) {
   ...;
   return ...;
}

const some_type get_some_type(...) {
   ...;
   return ...;
}

some_type後者 (値による戻り) を呼び出すことによる割り当ては、アプリケーションの実行中の特定の時点でデータの 2 つのコピーをメモリに残し、前者 (参照による戻り) を呼び出すことはこれを回避するという私の理解は正しいですか?

メモリ フットプリントを削減するという全体的な目標の一部としての別の取り組みは、some_type上記の参照によるリターン オプションの使用を排除する方法で の定義そのものを変更することでした。そのような場合、 since some_type(実際には種類のコンテナ、たとえば type のデータのコンテナdata_type) は、次のようにループ内で使用されます。

const some_type& = some_object->get_some_type(); // returns by ref. a large container
for(...) {
   ...;
   data_type = some_type.at(...);
   ...;
}

上記の値による戻り値を使用するように制約されている場合は、コンテナーの要素を値で取得する新しい関数get_some_type_atを導入して、次のように変更する必要があると思います (これを行うことの欠点はありますか?たとえば、パフォーマンスを意識していますか?):

for(...) {
   ...;
   data_type = some_object->get_some_type_at(...); // returns by value a small object
   ...;
}

繰り返しますが、私はこれらの側面の確認を主に探しています。しかし、詳細と洞察が最も高く評価されます。お時間と関心をお寄せいただきありがとうございます。

4

2 に答える 2

3

ほとんどの優れたコンパイラは戻り値の最適化を実装しているため、不要なコピー オブジェクトの作成について心配する必要はありません。

したがって、選択

some_type get_some_type(...) {
   ...;
   return ...;
}

古いコンパイラを使用していない限り。

(juanchopanza への謝辞。また、const オブジェクトの return をドロップします。コメントで説明します。)

詳細については、 http://en.wikipedia.org/wiki/Return_value_optimizationを参照してください。ここでこれを複製しても意味がありません。

于 2013-06-22T21:31:32.413 に答える
2

後者を呼び出すことによる割り当て (値による戻り) は、アプリケーションの実行中の特定の時点でデータ some_type の 2 つのコピーをメモリに残し、前者の呼び出し (参照による戻り) はこれを回避するという私の理解は正しいですか?

最新のコンパイラでは、その可能性は非常にわずかです。この標準では、このような場合にコンパイラが余分なコピーを作成しないようにするために、戻り値の最適化と呼ばれるもの (および名前付きの戻り値の最適化) を具体的に祝福しています。私が認識している合理的に最新のすべてのコンパイラには、この最適化が含まれています。場合によっては (gcc など) 、コンパイラーに最適化を行わないように指示した場合でも、この最適化が行われます。最適化がオンになっていると、最適化を行わなかったコンパイラを見つけるには、10 年程度 (おそらくそれ以上) を検討する必要があります。

C++11 では、大きなオブジェクトを値で返す場合でも、問題を回避するためにさらに多くのことを行う「移動」機能が追加されています。

結論:あなたが間違った場所で見ているように見えます-クラスに明示的な移動コンストラクター(およびおそらく移動代入演算子)を追加することを検討したいかもしれませんが、一般的には値で戻り、幸せになる。

于 2013-06-22T21:34:43.660 に答える