eee*_*aii 28 c++ performance virtual
C++问题在这里.我有一个系统,我将拥有数百个给定超类的迷你子类.他们都会有一个"foo"方法做某事.或者......我将有一个带有一个名为"type"的整数的类,并使用一个巨大的switch语句来决定当我foo时该做什么.
性能是一个重要的考虑因素.非常重要.
问题是,使用switch语句与让C++通过vftable实现它的性能优势/惩罚是什么?如果我将它作为switch语句,我可以将常见的foo放在switch语句的顶部,而不太常见的那些放在底部,希望能够快速进行比较.尝试使用vftable获得这样的效果必然会依赖于编译器,即使我可以弄清楚如何做到这一点......
另一方面,如果没有这些丑陋的switch语句,我的代码将更容易处理.
小智 12
在虚拟机设计领域已经有一些关于这个主题的研究.通常,switch语句会更快,许多虚拟机使用切换语义而不是虚拟查找.从理论上讲,人们会认为虚拟表 - 一个恒定时间算法 - 会更快,但我们必须检查硬件如何看待虚拟表.
switch语句更易于编译器内联.这是一个很大的考虑因素,调用虚函数的实际行为是最小的,但是,推送和弹出整个堆栈帧是必要的,因为编译器不知道在运行时将调用哪个函数.
虽然现代架构在预测虚拟呼叫方面变得更好,但在switch语句中分支预测和硬件预取应该更容易.
许多使用虚拟分派的代码都需要使用基于堆的分配方案.动态内存分配是很多C++应用程序的瓶颈.
编译器决定如何处理 switch 语句,但它们使用了一些基本技术。
case 语句位于 switch 语句中的位置在任何一种情况下都没有区别。
与直接调用相比,虚函数有一定的开销。它涉及额外的偏移量和指针查找。对于除了最极端的性能考虑之外的所有情况,此成本可以忽略不计。与交换机相比,开销不在于虚拟查找,而在于函数调用本身。因此,在每种情况下仅调用函数的 switch 语句的执行效果与虚拟函数基本相同。
因此,与虚拟函数调用相比,switch 语句(带有跳转表)的“调度语义”本质上几乎是无关紧要的。如果所有“foo”方法都相对较小并且可以内联,则 switch 语句将开始执行得更好。switch 的另一个优点是您可以将通用代码放在 switch 之前并获得更好的寄存器/堆栈优化。
然而,存在大量的维护开销。这应该是您此时最关心的问题。为什么?因为代码中的性能瓶颈不太可能是切换登录,甚至不是函数调用,而是其他东西。在解决其他问题之前,解决这些低级性能问题是没有意义的。因此,请坚持使用目前提供更易于维护的代码的那个。