関数の戻り値を参照によって格納することでパフォーマンスが向上しますか? 関数の戻り値を変数にコピーできないため、次のコードが優先されるということですか?
string Foo()
{
string someString = "some string";
return someString;
}
const string &str = Foo();
編集:上記の例Foo()
では文字列を返していますが、私の質問は他のタイプのオブジェクトも返すことに関係しています。
関数の戻り値を参照によって格納することでパフォーマンスが向上しますか? 関数の戻り値を変数にコピーできないため、次のコードが優先されるということですか?
string Foo()
{
string someString = "some string";
return someString;
}
const string &str = Foo();
編集:上記の例Foo()
では文字列を返していますが、私の質問は他のタイプのオブジェクトも返すことに関係しています。
文字列が C++ で実装される方法は、文字の配列としてです。したがって、参照を使用する場合の主な利点は、メンバーごとのコピーを回避できることと、ポイントされるオブジェクトがそれ自体に渡されたオブジェクトであることです。これにより、大きな文字列または配列が関係する場合のパフォーマンスが向上します。あなたの例では、文字列は本当に短く、それほど重要ではありません! お役に立てれば :)。
いいえ。実際には、パフォーマンスがわずかに低下する可能性があります (私はそれを疑っていますが)。この場合、参照を使用することで得られるのは難読化だけです。
今日のコンパイラは十分に賢く、おそらくそのような場合に RVO (戻り値の最適化) を使用するでしょう。したがって、値で返されたとしても、コピーのオーバーヘッドは存在しません
従うべき主なルールは、読みやすいコードを書くこと (コードは人のために書かれているため) であり、ボトルネックが見つかった後でのみ、必要な場合にのみ最適化を行うことです。
パフォーマンスが向上することはありません。この場合、 std::move() を使用してブーストを得ることができます。
現状のコードには、次の 2 つのコピーが含まれていますFoo
。
string
(1)コンストラクターを使用してconst char*
構築された型の一時オブジェクトからsomeString
.
(2) 変数someString
から の戻り値である一時オブジェクトへFoo
。
3 番目のコピーを防止する意図ではconst string &str = Foo();
なく、次のように書いています。const string str = Foo();
(3) の戻り値である一時オブジェクトからFoo
、 へstr
。
3 つのコピーはすべて標準で省略が許可されているため、問題は基本的に、コンパイラが 3 のサポートを必要とするかどうかです。
経験則として、ノーと言うでしょう -- あなたのコンパイラがコピー 1 と 2 を削除するのに十分賢いなら、おそらく 3 を削除するのに十分スマートです。パフォーマンスを向上させるには、関数Foo
とそれを呼び出すコードで作業する必要があります。しかし、このような状況は発生しません。最適化をオンにすることを忘れない限り、実際の C++ コンパイラはコピー省略を実行できます。
除外が許可されている一部のコピーを除外できない場合に、コンパイラがそれを回避できるように、コードを慎重に記述する必要がある特殊なケースが考えられます。これらのケースは発生時に見つける必要があります。(1) と (2) ではなく (3) について心配する必要があることを (正確に) 伝えることができる一般的なコーディングガイドラインはありません。