为了获得性能而避免多态性值得吗?

use*_*311 4 c++ polymorphism

为了获得性能而避免多态性值得吗?

我在Stroustrup的书中读到,多态函数调用比普通函数调用贵25%。这是否意味着我应该尽可能避免多态?我的意思是我应该一直在思考类似的事情:OK多态性可以解决此问题,但可能会破坏性能……或者鉴于现代CPU的强大功能,我什至不敢这么认为?

das*_*ght 6

我在 Stroustrup 的书中读到,多态函数调用比普通函数调用贵 25% 以内。这是否意味着我应该尽可能避免多态性?

不,绝对不是!非虚拟调用非常快,因为调用本身通常是一条指令。虚拟调用需要额外的间接级别;这就是所谓的 25% 的来源,但这是“纯粹的开销”,即您在比较两个无参数函数的调用时测量的开销。一旦开始添加参数,尤其是需要复制的参数,这两种开销之间的差距就会缩小:例如,将字符串按值传递给虚拟和非虚拟函数会使这种差距很难衡量。

此外,更昂贵的只是调用指令本身,而不是函数。调用函数的开销只占函数总时间的一小部分。函数越长,调用开销所占的百分比就越小。

总的来说,您应该努力提高代码的可理解性。如果添加带有虚函数的子类可以更容易地理解您的设计,那么您无论如何都应该使用子类化。运行代码的硬件每年都在变得更快,因此从长远来看,可读性会更胜一筹。


Mik*_*son 5

我在Stroustrup的书中读到,多态函数调用比普通函数调用贵25%。

可能是这种情况(可能是个大概的数字),但并不是那么重要。即使虚拟函数调用比普通函数调用贵25%,这仍然仅仅是函数调用的开销,而不是函数执行的开销。我只是想提高精度。函数调用的成本通常会比函数执行的成本小得多。但是请注意,如果您滥用多态并将其用于所有功能,即使是最琐碎的功能,它也不总是无关紧要的,那么额外的开销可能会很快加起来。

但是,最重要的是,虚函数调用必须通过函数指针进行分派,并且函数指针意味着没有内联或任何形式的跨上下文优化。通常,这是大多数减速的原因,例如,您不应将“虚拟函数调用”与“函数调用”进行比较,而应将“虚拟函数调用”与“静态可分析的,可能是内联的-能够进行lto优化的函数调用”。

为了获得性能而避免多态性值得吗?

在C ++和一般的编程中,只要有价格,就有收益,只要有收益,就有价格。就这么简单。动态多态性的代价是:(1)函数调用的开销;(2)阻止静态分析和优化;(3)通常需要堆分配的对象和额外的间接调用(指针,引用等),等等。继续,仅举几例。但是,您还可以从以下方面获得实质性的好处:(1)运行时灵活性,(2)可伸缩性(问题域的不相交并集),(3)减少编译时间,(4)减少代码重复等。

关键是,如果您想要多态可以买到的东西,那么您应该使用它。但是,如果您不需要这些东西(您会惊讶地发现您不需要这些东西的频率),那么您就不必为此付出不必要的代价。就这么简单。

有关替代方案和折衷方案的更多详细信息,我建议本文