0

短時間に何百万回も呼び出される関数やメソッドにパラメーターを渡すと、そのパラメーターを渡すオーバーヘッドが現れ始めます。

void foo(const SomeType&st){...}

std :: string、std :: vectorなどのタイプの場合、無意味なコピーが発生しないように、参照を渡すのがルールです。ただし、double、intなどのPODを扱う場合、話はまったく異なります。

パフォーマンスに関して、関数/メソッドがパラメーターを変更する必要がない場合、参照、const参照、またはコピーのいずれを渡すかを決定するときに、「注意すべき点」は何ですか?

void foo1(SomeType& st)
{
   ...
}

void foo2(const SomeType& st)
{
   ...
}

void foo3(SomeType st)
{
   ...
}

void foo4(SomeType* st)
{
   ...
}
  • int / unsigned intは常にコピーで渡されるべきですか?
  • ダブルは64ビット以上のターゲットでのみコピーで渡されるべきですか?
  • 関数をインライン化できる場合、パラメーターはどのように渡されますか?
  • ref / const refで渡す場合、エイリアシングは問題にどのように影響しますか?
  • どのような状況で、パラメーターの明示的なコピーがスタック上で有益でしょうか?

注:これは、const-correctnessに関する質問ではありません。また、32/64ビットプラットフォームでのgccおよびmsvcに関連する回答を探しています。

関連する可能性のあるいくつかのQ/A:

「constT&arg」と「Targ」

https://stackoverflow.com/a/2139254/754951

C++での参照/値の受け渡し

なぜ値ではなくconst参照を渡すのですか?

4

1 に答える 1

6

最善の答えは、プラットフォームの呼び出し規約を読むことですが、一般に、小さいタイプ(レジスターに収まるタイプ、または場合によっては少し大きいタイプ)の場合、通常、値を渡す方が高速です。ポインターまたは参照を渡す場合、ポインターは値によって渡されます。これには、元のオブジェクトをコピーするのと同じコストがかかり、さらに逆参照が必要になります。

オブジェクトが大きくなると、ポインターと逆参照のコピーのコストは通常​​、大きなオブジェクトのコピーのコストよりも小さくなるため、参照を使用する必要があります。オブジェクトを変更する予定がない場合は、を渡しconst&ます。

int / unsigned intは常にコピーで渡されるべきですか?ダブルは64ビット以上のターゲットでのみコピーで渡されるべきですか?

32ビットアーキテクチャでも、intとdoubleを値で渡す必要があります。繰り返しになりますが、アーキテクチャの呼び出し規約を確認してください(通常はコンパイラで文書化されています)。

関数をインライン化できる場合、パラメーターはどのように渡されますか?

関数がインライン化されている場合、コンパイラーはそれを最適化できます。たとえば、元のオブジェクトの代わりに参照を使用することで、参照のコストを削減できます。

ref / const refで渡す場合、エイリアシングは問題にどのように影響しますか?

(質問で主張するように)引数を変更しない場合は、エイリアシングは重要ではありません。アルゴリズムが予期しない方法で変更できるポインタ/参照を渡すと、エイリアシングの問題が発生します。

どのような状況で、パラメーターの明示的なコピーがスタック上で有益でしょうか?

スタック部分を無視する:オブジェクトが小さい場合。使用される呼び出し規約はスタックを使用しない場合があることに注意してください(レジスターで値を渡す場合があります)。さまざまな呼び出し規約についてこの記事を読むことをお勧めします

于 2012-05-26T22:27:49.633 に答える