|
現: 2016-03-31 (木) 15:22:08 takatsuka  |
| | + | 関数の中で、同じメンバ変数を何度も参照するような場合、ローカルにコピーしたほうが処理は早い場合が多いです。 |
| | + | 例えば List1 のようなコードがあったとします。 |
| | | | |
| | + | -List1 |
| | + | #prettify{{ |
| | + | class CTest |
| | + | { |
| | + | private: |
| | + | CClassA *m_pClassA; |
| | + | public: |
| | + | void Proc(); |
| | + | } |
| | + | |
| | + | void CTest::Proc() |
| | + | { |
| | + | m_pClassA->SetNumber(1); |
| | + | m_pClassA->SetCount(2); |
| | + | m_pClassA->Proc(); |
| | + | } |
| | + | }} |
| | + | |
| | + | CTest::Proc 関数で、m_pClassAを3回参照しています。 |
| | + | もし、m_pClassA の値が関数内で変わることがないのであれば、m_pClassA をローカル変数にコピーして、それを参照するようにしたのが List2 です。 |
| | + | |
| | + | -List2 |
| | + | #prettify{{ |
| | + | void CTest::Proc() |
| | + | { |
| | + | CClassA* const pClassA = m_pClassA; // ローカル変数にコピー |
| | + | pClassA->SetNumber(1); |
| | + | pClassA->SetCount(2); |
| | + | pClassA->Proc(); |
| | + | } |
| | + | }} |
| | + | |
| | + | なぜ、わざわざローカル変数にコピーする必要があるかというと、List1 は実は以下のコード list3 と同等です。 |
| | + | |
| | + | -List3 |
| | + | #prettify{{ |
| | + | void CTest::Proc() |
| | + | { |
| | + | CClassA *pClassA; |
| | + | pClassA = this->m_pClassA |
| | + | pClassA->SetNumber(1); |
| | + | pClassA = this->m_pClassA |
| | + | pClassA->SetCount(2); |
| | + | pClassA = this->m_pClassA |
| | + | pClassA->Proc(); |
| | + | } |
| | + | }} |
| | + | |
| | + | コンパイラは、変数m_pClassAが保持するCClassAのポインタを、毎回読み直すコードを吐きます。 |
| | + | そのため、プログラマがそれをさせないコードにすればムダは省けます。 |
| | + | |
| | + | 賢いコンパイラならこの程度の最適化は勝手にしてくれると考えるかもしれませんが、この場合はされません。 |
| | + | |
| | + | コンパイラは、 |
| | + | m_pClassA->SetNumber(1); |
| | + | という関数の中で、CTest::m_pClassA が変更される可能性がある為 m_pClassA をキャッシュしておくことはしません。 |
| | + | その為、次に m_pClassA を参照する場合も律儀に読み直す必要があるのです。 |
- 技術系備忘録/C++/最適化小手先テクニック/メンバ変数の参照は控えめにすべし のバックアップ差分(No. All)
Counter: 2964,
today: 1,
yesterday: 3