質問
私は次のように見える関数を持っています:
// Fetch 1 MB of data
void GetData(std::vector<char> & outData);
1MBは誇張されていますが、不要なコピーを避けることが望ましいと主張したいだけです。
この過負荷を追加すると:
std::vector<char> GetData()
{
std::vector<char> result;
GetData(result);
return result;
}
それでは、RVOがキックインする可能性はどれくらいですか?
解決
最も合理的に最近のコンパイラ(たとえば、2005年以降、GCC 3.4以下)があるため、本質的に確実です。存在するすべてのコンパイラをテストしていないので、「ほとんど」としか言いません。おそらく過去5年ほどで私が見たすべての新しいコンパイラが含まれています。
他のヒント
RVOは非常にシンプルな最適化であり、かなり長い間利用可能であるため、おそらくキックインするでしょう。ただし、このコードを適度に高性能コードでも実用的なコードに与えるために、NRVOが必要になります。 NRVOは比較的新しいため、出会うのが難しいです。それでも利用可能です。一例として、MSコンパイラはVS2005以来それを実装しています。
これに対する標準的な答えはないと思います。それはあなたのコンパイラとそれが何ができるかによって異なります。
便利なためにこれを実装することを考えている場合は、コンパイラーに参加してアセンブリを見たり、プロファイルして何が起こるかを確認してみませんか?コンパイラが実際に行うことについての経験的証拠は、おそらく一部のコンパイラーが何をするか、そうでないかを推測するよりも優れています。
それでは、RVOがキックインする可能性はどれくらいですか?
コンパイラではなく、考えるべきソフトウェア開発者の仕事です。
コンパイラは通常、良いコードをうまく機能させるように最適化されています - 悪いものではありません。
個人的には、最初のフォームを使用しています。通常、参照の代わりにポインターがあります - パラメーターが入力ではなく出力の事実であるという事実を強調します。
また、あなたが言うときに注意してください:
std::vector<char> GetData()
{
// :
return result;
}
vector<char> x = GetData();
カリーで、 result
「返品値」にコピーされ、その後、発信者では「返品値」がコピーされます x
. 。 NRVOは、これらのコピーの1つを取り除くことができますが、両方ではありません。コンパイラは、コピーCTORに行わなければならない副作用があると仮定する必要があるため、コピーを少なくとも1回呼び出す義務があります。