この質問に答える前に、分岐予測も考慮してください。
関数ポインタを使用して、条件文を関数の呼び出しに置き換えることができるシナリオがいくつかあります。このようなものがあります。(同様のタイプのシナリオでは、継承よりもコンポーネントベースのプログラミングを考えることができます)
class Shape
{
float Area()
{
if(type == SQUARE)
{
return length*length;
}
else if(type == RECTANGLE)
{
return length*breadth;
}
}
}
同じクラスをこのように書くことができます。
class Shape
{
void SetAreaFunction(void *funcptr)//this function is used to set the current AreaFunc
{
CurrentAreaFunc = funcptr ;//this holds the pointer to current area func
}
float SqauareArea();//this will return square area
float RectangleArea();//this will return rectangle area
float Area()
{
currentAreaFunc();
}
}
上記の場合を考えれば、どちらも同じ結果になりますが、パフォーマンスのオーバーヘッドを考えています.2番目のケースでは、関数呼び出しを行うことで分岐予測の問題を回避しています。
ここで、この種のシナリオでどちらがより良いプラクティスであり、「より適切に最適化されたコード」であるかを教えてください(ところで、「時期尚早の最適化はすべての悪の根源である」というステートメントは好きではありません。コードの最適化を検討してください!)
PS:アセンブリコードでも、「分岐予測がいかに悪いか」について詳細な概要を説明してもかまいません。
更新:プロファイリング後(上記のコードと同様の種類)、
Conditionがこの種のシナリオで成功した場合、誰かがこれの理由を説明できますか?分岐コードがないので、機能呼び出しコードをプリフェッチできますか?しかし、ここでは逆に見えます。分岐コードが勝ちます!:O Intel Mac Osx、GCC O3/Os最適化でプロファイルされます。