哪一个更快?函数调用或条件if语句

Which one is faster ? Function call or Conditional if Statement?

本文关键字:条件 if 语句 函数调用 哪一个      更新时间:2023-10-16

请在回答这个问题之前也考虑一下分支预测。

我有一些场景,我可以用函数指针的帮助下调用函数来替换条件语句。像这样的东西。(对于类似的场景,您可以考虑基于组件的编程而不是继承)

     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();
        } 
     }

如果你考虑上述情况,两者都达到相同的结果。但是,我考虑的是性能开销。在第二种情况下,我通过函数调用来避免分支预测问题。

现在让我知道在这种情况下哪个是更好的实践和"更好的优化代码"。(顺便说一句,我不喜欢"过早优化是万恶之源"的说法,因为优化有它的好处,所以我确实考虑优化我的代码!)

p。S:我不介意有人给出一个详细的概述,关于即使在汇编代码中"分支预测有多糟糕"。

更新:在分析之后(类似于上面的代码),
如果Condition在这种情况下成功。有谁能给出一个理由吗?函数调用代码可以预取,因为没有分支代码对吗?但在这里,它看起来是另一种方式……分支代码获胜!:阿在Intel Mac Osx,GCC O3/Os优化上配置

您用间接语句替换了if语句。

if语句和间接语句都需要内存访问。

然而,if将导致一个短暂的跳转——这可能不会使管道失效,而间接操作可能会使管道失效。

另一方面,间接语句是跳转,而if语句是条件跳转。分支预测器可能会错过

如果不进行测试,很难判断哪个更快。我预测if语句将获胜。

请分享你的成果!

您需要对这些代码进行概要分析,以便能够针对特定环境(编译器、编译器版本、操作系统、硬件)做出特定语句,并且您需要在特定应用程序中进行度量,以便能够知道这对该应用程序是否重要。除非您正在编写库代码,否则不要费心,除非分析显示这是应用程序中的热点。

只写最易读的代码,最容易维护。优化干净、无bug、易读的代码总是比修复bug优化后的代码更容易。

这就是说,我记得Lippman在他的 c++对象模型中引用了一项研究,该研究发现虚函数(基本上是函数指针)至少与在实际应用程序中切换类型一样快。我不知道具体细节,但书里肯定有。

更有可能的是,优化器可以在if语句上应用他的魔法,然后在动态变化的函数指针上应用。只是猜测,理论上编译器可以做任何他能证明不会改变语义的事情。

但是在你做调用一个函数,而只实现一个分支(在你的情况下使用if)的情况下,CPU更有可能应用它的魔法,即重新排序指令,预取东西等。如果在大多数cpu之间有一个函数调用,很可能会"刷新"它们的管道,cpu优化将无法实现。

也就是说,如果你把所有东西都放在一个头文件中,调用者和被调用者,编译器可能会取消函数调用,会自己重新排序,等等。

试着自己测量一下。称之为1M次。C++11使用<chrono>, monothonic_clock::now() .

Update:我的经验是:不要过度优化你的代码——这很可能会让它变得更糟。让编译器完成这项工作,并为此使尽可能多的代码对它可见。如果你这样做,你肯定需要一个分析器,尝试一些替代方案,使用它们提供给你的提示。但不要忘记:这必须非常仔细地进行微调。性能的唯一度量是速度。还有可读性可测试性可重用性等等。引用Donald Knuth的话:"过早优化是万恶之源。"