2009-05-01 11 views
4

私はよく書かれていないと思われる既存のC++コードに取り組んでおり、頻繁に呼び出されています。私はそれを変更する時間を費やすべきか、あるいはコンパイラが問題を既に最適化しているかどうか疑問に思います。あなたは確信している場合はC++の最適化

void someDrawingFunction(....) 
{ 
    MyContext &c = GetContext(); 
    c.DrawSomething(...); 
    c.DrawSomething(...); 
    c.DrawSomething(...); 
    . 
    . 
    . 
} 
+0

これはVisual Studio 2008ですか? – epotter

+0

私はこの種の最適化を最近行う必要がありました。そして、私はそれを行う前にコードをプロファイリングしました。 – Constantin

+0

キャッチエポターに感謝します。 VS 9(2008)を2009年に組み合わせるには、私に任せてください。:-) –

答えて

11

が、それはです:

ここ
void someDrawingFunction(....) 
{ 
    GetContext().DrawSomething(...); 
    GetContext().DrawSomething(...); 
    GetContext().DrawSomething(...); 
    . 
    . 
    . 
} 

が、私はそれを行うだろうかです:私は、Visual Studioここでは2008

を使用してい

は一例ですパフォーマンスの問題、それを変更します。 GetContextが(マクロまたはインライン関数とは対照的に)関数呼び出しである場合、コンパイラは毎回それを呼び出す必要があります。なぜなら、コンパイラは何をしているのかを必ずしも見ることができないからです。それが電話を消すことができることを知っている。

もちろん、GetContext ALWAYSが同じことを返すことと、この「最適化」が安全であることを確認する必要があります。

+0

絶対に。 "DrawSomthing"コンテキストでは、おそらく、すべてのGetContext()が同じであることが本当です。 – dmckee

+0

描画関数内では、GetContext()は常に同じオブジェクト参照(私が作業しているコードのメンバ変数)を返します。 Adamの提案によれば、私は後でいくつかのプロファイリングを試み、いくつかのテストの変更がパフォーマンスに影響を与えるかどうかを確認します。 何十万というオブジェクトを画面に描画するときに、私は最小限の改善をしてもうれしいです。 –

+0

また、GetContext()が変数のゲッターのようなものであれば、おそらくローカル変数と同じくらい高速です。それがかなり複雑な場合は、ここでパフォーマンスを失うかもしれません。テストとプロファイリングは唯一の方法です。 –

25

プログラムの所要時間を推測しないでください。 最初にボトルネックを見つけて最適化してください。

GetContext()については、どれほど複雑であるかによって異なります。クラスメンバー変数を返すだけの場合は、コンパイラがインライン展開する可能性があります。 GetContext()がより複雑な操作(テーブル内のコンテキストを参照するなど)を実行する必要がある場合、コンパイラはおそらくそれをインライン展開していないので、2回目のスニペットのように1回だけ呼び出すことをお勧めします。

GCCを使用している場合は、GetContext()の機能にpure attributeというタグを付けることもできます。これにより、common subexpression eliminationなど、より多くの最適化を実行できます。

+1

+1:プロフィール。あなたが変更を加える前に、ユニットテストのセットを持ってください。単体テストは、簡単に何かを壊して、決して知らないことを意味しません。 –

+0

+1。特に、コンパイラは、インライン化するか、または純粋であり、安全に最適化することができるかを判断するために、同じ変換単位(たとえば、ヘッダー経由)でGetContext()のソースコードを参照する必要があります。 –

+0

GetContext()がインライン化されていなくても、この「最適化」が測定可能な差異を生み出すとは思われません。あなたはプロフィールを持っている! –

2

明らかに、GetContext()に副作用(I/O、グローバルの更新など)がある場合、推奨される最適化よりも異なる結果が生じることは明らかです。

コンパイラが何らかの形でGetContext()が純粋であることを検出できない限り、それを自分で最適化する必要があります。

8

論理的に2番目の方法、つまりGetContext()を複数回呼び出すことはプログラムロジックには影響しません。プロファイルを作成してもそれがあると証明しても2番目の方法ですどちらの方法でもパフォーマンスの差はないので、このコードを見ている次の開発者は同じ質問を再び聞かないでしょう。

+1

私はこれに同意します。最適化とは別に、GetContext()を複数回呼び出すと、プログラマーはGetContext()が*何をしているかを尋ねて、複数回呼び出す必要があります。 –

1

コンパイラが何をしているのか疑問に思うなら、アセンブリコードを見てください。

+0

問題は、このコンパイラが現在何をしているのかを示しています。次のバージョンではできません。このようにしていくつかのスロースポットを見つけることができます(ただし、アセンブリコードのパフォーマンスは以前よりもはるかに不透明です)。ただし、次のサービスパックのような他の条件では構造が安全でない場合は見つかりません。 –

+0

さて、はい。しかし、コンパイラが何をしているのか不思議であれば、ASMは見るのが良い場所です。 –

0

これは簡単な変更ですが、私はそれを行います。
それを討論するよりも速く修正します。

実際に問題がありますか?
頻繁に呼び出されているからといって、頻繁にTOOと呼ばれるわけではありません。
質的にピギーがある場合、sample itで時間を過ごしてください。
ではなく、と推測している可能性があります。