メンバ変数の参照は控えめにすべし

メンバ変数の参照は控えめにすべし

関数の中で、同じメンバ変数を何度も参照するような場合、ローカルにコピーしたほうが処理は早い場合が多いです。
例えばList1 のようなコードがあったとします。

List1

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
void CTest::Proc()
{
    CClassA* const pClassA = m_pClassA; // ローカル変数にコピー
    pClassA->SetNumber(1);
    pClassA->SetCount(2);
    pClassA->Proc();
}
なぜ、わざわざローカル変数にコピーする必要があるかというと、上記コードは実は以下のコード list3 と同等ですの意味です。
List3
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 を参照する場合も律儀に読み直す必要があるのです。
 




サイト名: シンクリッジ   http://www.thinkridge.com
この記事のURL:   http://www.thinkridge.com/modules/tinyd1/index.php?id=2