ルーチンが(N)RVOを利用していることを確認できますか?
-
09-12-2019 - |
質問
私のルーチンは可能な限りルーチンを活用していることを確認したいのですが。結果として生じる分解を通して解析以外に、私が行うことができるものがありますか、またはルーチンが(n)RVOでコンパイルされているかどうかを確認することができますか?この時点で、私は主にMSVCとGCCに興味があります。
解決
いいえ、実際にはありません。
しかしあなたはあなたのコードを書くときにガイドラインに従うことができます。
名前の戻り値最適化
デバッグモードでも一時的な復帰するたびにこれはほとんどトリガーされていません。
.
return MyObject(....);
名前の戻り値最適化
関数が常に同じ一時オブジェクトを返すたびにこれはほとんどトリガーされます。
.
MyObject func() {
MyObject result;
if (...) { return result; }
result.push(0);
return result;
}
あなたはそれらを混ぜることができますが、この場合、コンパイラがRVOを適用するのは不可能になることが不可能になります。
.
MyObject func() {
MyObject result;
if (...) { return MyObject(...); }
return result;
}
ここで、1つの復帰がRVOから恩恵を受けることはおそらく、もう一方はそうではありません。そして、戻りスロットにresult
を発見的に作成し、突然if
ブランチを受講する必要がある場合は、最初に最適化されたことに賭けます。ステートメントを並べ替えるだけで、
.
MyObject func() {
if (...) { return MyObject(...); }
MyObject result;
return result;
}
だからNRVOの経験則は、return
の宣言とresult
自体よりも他のものを返すreturn result;
ステートメントの間にresult
ステートメントがないことです。
これに従うならば、あなたはあなたの好意の中でオッズを積み重ねます。それからそれはコードレビューの問題です。
そしてあなたはあなたが本当にそれらを必要とすることを知る前にあなたが変数を宣言しないので、あなたのコードを読むことをより簡単に読みやすくしましょう!
他のヒント
デバッグメソッドをデストラクタに追加できます。
struct A
{
~A() { cout << "destructor called"; }
};
A foo()
{
A a;
return a;
}
.
デストラクタが呼び出された場合、RVOはおそらく適用されなかった。
可能な方法は次のとおりです。
-
クラスを通して作成されたインスタンスの数を追跡するクラス内の参照カウントメカニズムの実装このようにして、このようにして作成され、削除されたクラスの追加コピーを検出できます。コピー除去は起こらない。
-
コピーのリージョンが起こっていない場合は、Copy ConlictorとDestructorのCopy ConstructorとDestructorにデバッグトレースを配置することができます。