Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 迭代而不产生IF语句的开销_C++ - Fatal编程技术网

C++ 迭代而不产生IF语句的开销

C++ 迭代而不产生IF语句的开销,c++,C++,我的问题是基于好奇心,而不是是否有其他方法来解决这个问题。这是一个奇怪/有趣的问题,请以开放的心态阅读 让我们假设有一个每帧都被调用的游戏循环。游戏循环依次通过无数的if语句调用多个函数。例如,如果用户将GUI设置为false,则不要刷新GUI,否则请调用RefreshGui()。循环中还有许多其他if语句,如果它们为true,则调用各自的函数。有些是if/if-else…/else,在最坏的情况下成本更高。如果if语句为true,则即使调用的函数也具有逻辑性。如果用户希望在所有对象上进行光线拾

我的问题是基于好奇心,而不是是否有其他方法来解决这个问题。这是一个奇怪/有趣的问题,请以开放的心态阅读

让我们假设有一个每帧都被调用的游戏循环。游戏循环依次通过无数的
if
语句调用多个函数。例如,如果用户将GUI设置为false,则不要刷新GUI,否则请调用
RefreshGui()
。循环中还有许多其他
if
语句,如果它们为true,则调用各自的函数。有些是
if/if-else…/else
,在最坏的情况下成本更高。如果
if
语句为true,则即使调用的函数也具有逻辑性。如果用户希望在所有对象上进行光线拾取,请调用
function()
,如果用户希望在灯光上进行光线拾取,请调用FunctionB(),否则调用所有函数。希望你能明白

我的观点是,这是很多冗余的if语句。所以我决定改用函数指针。现在我假设函数指针总是比
if
语句快。它是if/else的替代品。因此,如果用户想要在两种不同的相机模式之间切换,他/她可以按
C
键在它们之间切换。键盘的回调函数将函数指针更改为正确的
UpdateCamera
函数(在这种情况下,函数指针可以指向
UpdateCameraFps()
UpdateCameraArcBall()
)。。。你明白要点了

现在谈谈问题本身。如果我有几个具有相同签名的更新函数(比如void
(*update)(float time)
),那么函数指针可能会指向其中任何一个。然后,我有一个用于存储指针的向量。然后在我的主更新循环中,我遍历向量并调用每个更新函数。我可以删除/添加更新,甚至更改更新顺序,而无需更改底层代码。在最好的情况下,我可能只调用一个update函数,或者在最坏的情况下调用所有函数,所有函数都使用非常干净的while循环,并且没有讨厌的(可能嵌套的)if语句。我已经实现了这个部分,它工作得很好。我知道,对于负责遍历向量的while循环的每次迭代,我都在检查
itrbegen==itrEnd
。更具体地说,
while(itrbegen!=itrEnd)
。有没有办法避免调用if语句?我可以使用分支预测来发挥我的优势吗(或者我已经在不知不觉中利用了它)

同样,请按原样回答这个问题,也就是说,我不是在寻找一种不同的方法(尽管非常欢迎您给出一种方法)

编辑:一些回复指出,这是一个不必要的过早优化,我不应该把重点放在它上面,与所有单独的更新函数中所做的工作相比,if语句的成本是微不足道的。非常正确,我完全同意,但这不是问题的重点,如果我没有把问题说清楚,我很抱歉。尽管如此,我还是从所有的回复中学到了不少新东西


如果ifs检查的条件在循环过程中没有改变,则可以全部检查一次,并设置一个函数指针,指向在这种情况下要调用的函数。然后在循环中调用函数指针指向的函数

每一帧都有一个游戏循环

这是一种倒退的描述方式。游戏循环不会在帧期间运行,而是在游戏循环的主体中处理帧

我的假设是函数指针总是比if语句快

你测试过了吗?这不太可能是真的,特别是如果您经常更改指针(这确实会干扰CPU的分支预测)

我可以使用分支预测来发挥我的优势吗(或者我已经在不知不觉中利用了它)

这只是一厢情愿。通过在循环中调用一个间接调用一组不同的函数,您肯定是在违反CPU分支预测逻辑

更具体地说,while(itrbeing!=itrEnd)。有没有办法避免调用if语句


为了避免在迭代函数链时使用条件,可以使用链表。然后,每个函数都可以无条件地调用下一个函数,只需将终止逻辑作为链中的最后一个函数(longjmp或其他函数)安装即可。或者,您可以希望永远不要终止,在列表中包括
glSwapBuffers
(或图形API的等效项),并将其链接回开始处。

对我来说,这是一种事件驱动的方法。与其每次都检查是否需要执行某项操作,不如监视传入的执行某项操作的请求

我不知道你是否认为它偏离了你的方法,但是它会减少IF的数量,然后将语句减少到1。< /P>
while( active )
{
    // check message queue
    if( messages )
    {
        // act on each message and update flags accordingly
    }

    // draw based on flags (whether or not they changed is irrelevant)
}

编辑:我也同意海报上的说法,循环不应该基于框架;帧应该基于循环。

首先,分析代码。然后优化需要它的部件

“如果”陈述是你最不关心的。通常,通过优化,您将重点放在循环、I/O操作、API调用(例如SQL)、效率低下且经常使用的容器/算法上


使用函数指针进行优化通常是最糟糕的事情。您会扼杀任何代码可读性的机会,并与CPU和编译器对抗。我建议使用多态性或只使用“if”语句。

如果这些函数中的每一个都在执行“大型”任务(如刷新GUI),那么进行单个比较的成本在比较中肯定是微不足道的?哈夫