0

たとえば、ポインタのベクトルをループして複数のオブジェクトをチェックし、それらに対して操作を実行しているとします。私は次のいずれかを行うことができました。

方法 1:

std::vector< Object* >::iterator it;
Object* o;
for (it = objects.begin(); it != objects.end(); ++it)
{
    o = (*it)
    if(o->GetActive())
    {
        o->method;
        o->method2;
        o->method3;
        //etc...
    }
 }

方法 2:

std::vector< Object* >::iterator it;
for (it = objects.begin(); it != objects.end(); ++it)
{
    if((*it)->GetActive())
    {
        (*it)->method;
        (*it)->method2;
        (*it)->method3;
        //etc...
    }
 }

私が見ることができることから、特に次のようなことをしている場合、構文を逆参照すると読みやすさが複雑になることが多いため、方法1の方が読みやすくなっています。

if((*o)->CheckValue((*c)))

ただし、ローカル変数を作成すると、読みやすくなります。

if(o->CheckValue(c))

しかし、メモリ コストを増加させる余分な変数を作成していますよね?

パフォーマンスの違いは何ですか?

4

3 に答える 3

3

最適化コンパイラは、おそらくそれらを同じにします。読みやすくするために、変数に割り当てると便利な場合があります。コンテナーにポインターが含まれていない場合は、代わりに参照を使用できます。

std::vector< Object >::iterator it;
for (it = objects.begin(); it != objects.end(); ++it)
{
    const Object &o = (*it)
    if(o.GetActive())
    {
        o.method();
        o.method2();
        o.method3();
        //etc...
    }
 }

編集:レイモンドがコメントで指摘しているように、メソッドが問題のオブジェクトを変更する可能性がある場合、コンパイラは特定の最適化を行うことができません。それを修正する方法はconst、可能な場合は使用することです。そのため、実際に示すように例を変更しました。これを行うと、マークされていないオブジェクトのメソッドを呼び出すことはできませんconst

于 2013-09-23T02:12:17.413 に答える
1

実際、別の構文を選択すると、選択が無関係になります。

for (Object* o : objects)
{
  // ... body
}
于 2013-09-23T07:55:53.767 に答える
0

周りにオブジェクトがない限りvolatile、ローカル オブジェクトを扱うときは、ほとんどの場合、読みやすさだけに帰着します。

あなたの特定のケースで*itは、コンパイラ実行しなければならない操作であり、その結果はレジスタで終了します。したがって、コンパイラが次の使用のために結果をとにかくレジスタに残すことはほぼ確実であり、したがって「暗黙的に」o変数を作成します。言い換えれば、アセンブリに降りると、その変数はそれ自体で発生します。

代わりに、逆参照間で変更されていないことをコンパイラが自明に証明できないit場合 (たとえば、それへのポインターまたはへのポインターobjectsが渡された場合、または非ローカルである場合)、またはこの種の最適化を回避するように明示的に指示されている場合は、別の状況です。 (volatileキーワード経由)。

于 2013-09-23T02:12:05.220 に答える