私はMyClass
のこれら2つのメンバ関数を持っていた:このコードをランタイムに影響を与えずに分解できますか?
Result MyClass::func1(const CommonParam& commonParam1, const CommonParam& commonParam2, const CommonParam& commonParam3, const ExtraParam1& extraParam1)
{
Result result;
// prolog code, common to all, using commonParam1, commonParam2, commonParam3
doSomething(1, commonParam1, commonParam2, extraParam1);
// epilog code, common to all, using commonParam1, commonParam2, commonParam3
return result;
}
Result MyClass::func2(const CommonParam& commonParam1, const CommonParam& commonParam2, const CommonParam& commonParam3, const ExtraParam2& extraParam2, const ExtraParam3& extraParam3)
{
Result result;
// prolog code, common to all, using commonParam1, commonParam2, commonParam3
doSomething(1, commonParam1, commonParam2, extraParam2, extraParam3);
// epilog code, common to all, using commonParam1, commonParam2, commonParam3
return result;
}
私は正確に両方の機能のために同じですプロローグ/エピローグコード(の重複を避けるために、これを因数分解する必要が修正MyClassの属性で、プロローグはで使用される変数を作成しますエピローグ...そのようなもの)。唯一の違いは、別のバージョンのMyClass::doSomething
が(異なるパラメータを使用して)呼び出されることです。 doSomething
は異なるパラメータセットと呼ばれているように、私は、テンプレートを使用してヘルパークラスを導入する因数分解のためにこのアプローチを使用:
class helper1
{
public:
helper1(const ExtraParam1& extraParam1) : extraParam1(extraParam1) {}
inline bool compute(MyClass& parent, const CommonParam& commonParam1, const CommonParam& commonParam2) const
{
return parent.doSomething(1, commonParam1, commonParam2, extraParam1);
}
private:
const ExtraParam1& extraParam1;
};
class helper2
{
public:
helper2(const ExtraParam2& extraParam2, const ExtraParam3& extraParam3) : extraParam2(extraParam2), extraParam3(extraParam3) {}
inline bool compute(MyClass& parent, const CommonParam& commonParam1, const CommonParam& commonParam2) const
{
return parent.doSomething(1, commonParam1, commonParam2, extraParam2, extraParam3);
}
private:
const ExtraParam2& extraParam2;
const ExtraParam3& extraParam3;
};
template<typename Helper>
inline Result funcT(MyClass& parent,
const CommonParam& commonParam1,
const CommonParam& commonParam2,
const CommonParam& commonParam3,
const Helper& helper)
{
// this function is a friend of MyClass, so prolog/epilog can use any private class attribute
Result result;
// prolog code, common to all, using commonParam1, commonParam2, commonParam3
helper.compute(parent, commonParam1, commonParam2);
// epilog code, common to all, using commonParam1, commonParam2, commonParam3
return result;
}
Result MyClass::func1(const CommonParam& commonParam1, const CommonParam& commonParam2, const CommonParam& commonParam3, const ExtraParam1& extraParam1)
{
return funcT(*this, commonParam1, commonParam2, commonParam3, helper1(*this, extraParam1));
}
Result MyClass::func2(const CommonParam& commonParam1, const CommonParam& commonParam2, const CommonParam& commonParam3, const ExtraParam2& extraParam2, const ExtraParam3& extraParam3)
{
return funcT(*this, commonParam1, commonParam2, commonParam3, helper2(*this, extraParam2, extraParam3));
}
これらの機能は、当社のアルゴリズムによって倍の十億と呼ばれていますので、リファクタリングが最低を持っている必要がありますランタイムインパクト。
compute
はinline
です。実行時の影響を最小限に抑えるために、すべてが参照渡しであり、仮想テーブルではなくテンプレートを使用しました。しかし、私は(少なくとも、我々はhelper1
、helper2
オブジェクトを作成します)これは、実行時に影響を与えていると思います。
私のリファクタリングは、コンパイラは削除しないことを、ランタイム影響がありますか? そうならば、誰かが低く、ランタイム影響がリファクタリングを提案しているだろうか?