虚拟或类型转换

时间:2011-12-24 07:18:47

标签: c++ casting event-handling polymorphism

我有一个问题。我正在尝试创建代码来更新我的游戏,但我陷入了“两难”。我不想使用虚拟和它的唯一原因是我在谈论的每个人(在论坛,聊天,朋友)说虚拟使代码真的很慢,所以我做了一个研究,发现它做的查找vtable可以将性能降低近一半。因此,我将它用于不需要每帧更新的任务。一切正常,直到我得到更新/渲染功能。然后我开始考虑寻找解决方法。有了一个想法,但首先我想问一下那些知道那个人的人在实施之前。

我的游戏引擎非常受事件驱动。我可以使用子系统之间的事件(图形,UI,脚本)发送任何类型的数据。所以,我正在考虑每帧发送一个事件“renderScene”。这对我来说听起来不错,但是有一个问题。事件处理程序的结构并不是很好,我现在真的不想改进它,因为它做得非常不错,我的目标是完成我的游戏,而不是修理引擎而永远不会完成它(碰巧我,所以不想再回到它了。)

我的事件处理程序有一个函数将事件注册到函数(我称之为处理程序)。但是这个函数的问题是,我需要做函数绑定和东西来注册成员函数。所以,我找到了一个解决方法 - 我创建一个静态函数并从中调用成员函数。这就是静态函数的样子:

void GraphicsSubsystem::renderScene(Subsystem * subsystem, Event * event) {
   GraphicsSubsystem * graphics = static_cast<GraphicsSubsystem *>(subsystem);
   graphics->renderScene();
}

void ScriptingSubsystem::runLine(Subsystem * subsystem, Event * event) {
   ScriptingSubsystem * scripting = static_cast<ScriptingSubsystem *>(subsystem);
   Event1<String> * e = static_cast<Event1<String> *>(event);
   scripting->runLine(e->getArg());
}

参数总是抽象子系统类和基本事件类。 runLine 函数我没有问题,因为我没有在每一帧上运行一行代码。但是, renderScene 功能让我有点不舒服。

tl;博士,这是我的问题。静态构建每个帧上的对象比在每个帧上调用虚函数更快吗?

4 个答案:

答案 0 :(得分:6)

是的,静态演员是一种非常快速的操作。静态强制转换是静态的,即所有参数在编译时都是已知的,并且在运行时,指针由常量修改。

但是,您也不应对虚函数调用过度悲观。虽然它们比正常的函数调用慢,但它们在很多时间尺度上仍然非常非常快,特别是与渲染场景的成本相比。我很难想象每帧O(1)虚拟函数调用使得游戏变慢。首先制作一个干净的设计,并在观察慢速游戏时担心速度慢,并且可以剖析以确定它的确切位置。

答案 1 :(得分:3)

一般的答案取决于具体情况。

但是,试着想象一下运行时对调用时虚函数的作用 - 它接受this指针,在虚方法表中查找函数的指针并运行该函数。

对我来说,目前还不清楚为什么这应该比你的静态施法慢。

如果我是你,我会使用这两种方法创建一个原型代码/存根,并调用它一百万次并测量其性能。

答案 2 :(得分:3)

这个question讨论了静态演员的成本,这是question虚拟调度的成本。后者解释说虽然vtable查找不是很昂贵,但丢失优化和缓存未命中对性能的影响可能会很明显。

因此,您的担忧至少值得考虑。 (我最初的想法是,确保渲染场景的工作肯定比调用函数的成本更重要。)

@ Jiri的评论肯定是正确的,真正知道的唯一方法是测量它 - 我们在这里讨论的效果非常特定于编译器/优化器/ CPU聪明。构建测试不会花费很长时间。

答案 3 :(得分:1)

如果您需要虚拟功能的功能,请使用它们。他们在那里因为它们很有用。

如果有一种简单有效的方法在您的系统上实现它,显然编译器实现者已经这样做了。

相信你的编译器!