只是为了摆脱它...Premature optimization is the root of all evil
Make use of OOP
etc.
我明白。只是寻找一些有关某些操作速度的建议,我可以将其存储在灰色物质中以备将来引用。
假设您有一个动画课。动画可以循环播放(一次又一次)或不循环播放(一次),它可以具有唯一的帧时间,等等。假设有3个“或”属性。请注意,Animation类的任何方法最多都将检查其中之一(即,这不是if-elseif的巨大分支的情况)。
这里有一些选择。
1)为它提供上述属性的 bool(boolean) 成员,并在播放动画以执行适当的操作时使用if语句对它们进行检查。
2)创建一个基础动画类,并派生其他动画类,例如LoopedAnimation和AnimationUniqueFrames等。
vector<Animation>
的内容,请在每次调用Vtable时检查播放动画的Vtable。同样,为所有可能的组合创建一个单独的类似乎会使代码过于庞大。 3)使用模板专门化,并专门依赖那些属性的那些功能。像
template<bool looped, bool uniqueFrameTimes> class Animation
一样。vector<Animation>
。也可能是肿的。 我想知道每个选项提供什么样的速度?我对第一个和第二个选项特别感兴趣,因为第三个选项不允许一个对象通过
Animation
的常规容器进行迭代。简而言之,什么是更快的-vtable访存还是有条件的?
最佳答案
(1)如今,所生成的程序集的大小已不再重要,而是它所生成的(近似地,假设x86上为MSVC):
mov eax, [ecx+12] ; 'this' pointer stored in ecx, eax is scratch
cmp eax, 0 ; test for 0
jz .somewhereElse ; jump if the bool isn't set
优化的编译器将在其中散布其他指令,从而使其更便于管道使用。无论如何,类的内容很可能仍在缓存中,如果不是,则在以后的几个周期中都将需要它。因此,回想起来,这可能是几个周期,对于每帧最多被调用几次的事情,那没什么。
(2)这大约是每次调用play()方法时都会生成的程序集:
mov eax, [ebp+4] ; pointer to your Animation* somewhere on the stack, eax is scratch
mov eax, [eax+12] ; dereference the vtable
call eax ; call it
然后,您将在专门的play()函数中有一些重复的代码或另一个函数调用,因为肯定会定义一些常见的东西,从而招致一些开销(代码大小和/或执行速度)。因此,这绝对慢。
而且,这使得加载通用动画更加困难。您的图形部门不会高兴。
(3)为了有效地使用它,最终还是要为模板版本创建一个带有虚函数的基类(在这种情况下,请参阅(2)),或者通过检查以下位置的类型来手动完成该工作:您称自己为动画对象,在这种情况下也请参阅(2)。
这也使得加载通用动画更加困难。您的图形部门将不那么高兴。
(4)您不必担心的是,对于最多在一帧内完成几次的细微事情,并没有进行微优化。通过阅读您的帖子,我实际上发现了另一个通常被忽略的问题。您提到的是std::vector 。没有什么可以反对STL的,但这是不好的伏都教。在整个应用程序运行期间,一次内存分配将比play()或update()方法中的所有 bool(boolean) 检查花费更多的周期。将动画放入std::vectors以及从其中放入动画(尤其是如果您放入实例而不是实例的指针(智能或哑巴))将使您花费更多。
您需要在不同的地方进行优化。如此荒谬的微优化不会给您带来任何好处,只会使您的图形部门难以一概而论。然而,重要的是担心内存分配,然后,当您完成对该部分的编程之后,启动探查器并查看热点在哪里。
如果保留动画实际上已成为瓶颈,则可以在std::vector(很不错的地方)找到它。例如,您是否看过侵入式链表?这实际上比担心这一点更有益。
关于c++ - 速度比较-模板特化vs.虚函数vs.If语句,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2830941/