美好的一天,
假设您有一个简单的for循环,如下所示......
for(int i=0;i<10;i++)
{
//statement 1
//statement 2
}
假设陈述1和陈述2为O(1)。除了&#34;开始&#34;另一个循环,会将for循环分解成两个(不是嵌套的,但顺序的)循环同样快吗?例如......
for(int i=0;i<10;i++)
{
//statement 1
}
for(int i=0;i<10;i++)
{
//statement 2
}
为什么我问这样一个愚蠢的问题是我有一个碰撞检测系统(CDS)必须遍历所有对象。我想&#34;区分&#34;我的CDS系统的功能,所以我可以简单地调用
cds.update(objectlist);
而不是打破我的CD系统。 (不要太担心我的CDS实施......我想我知道我在做什么,我只是不知道如何解释它,我真正需要知道的是,如果我采取一个巨大的循环遍历所有对象再次。
答案 0 :(得分:4)
就算法复杂性而言,分割循环没有区别。
就真实世界性能而言,分割循环可以提高性能,恶化性能或没有差别 - 这取决于操作系统,硬件,当然还有statement 1
和statement 2
。< / p>
答案 1 :(得分:3)
这取决于您的申请。
可能的缺点(分裂):
可能的收益(分裂):
这些列表肯定不全面,但您已经可以感觉到代码和数据之间存在紧张关系。因此,当我们都不知道时,我们很难接受教育/猜测。
有疑问:个人资料。使用callgrind,检查每种情况下的缓存未命中,检查执行的指令数。衡量花费的时间。
答案 2 :(得分:2)
有两个循环你将支付:
最后一点可能会对这两个方向产生巨大影响。您应该像任何性能优化一样进行测量。
答案 3 :(得分:1)
就大的复杂性而言,如果1个循环是O(n),这就没有区别,那么2循环解决方案也是如此。
就微观优化而言,很难说。循环的成本相当小,我们不知道访问对象的成本是多少(如果它们在向量中,那么它也应该相当小),但要提供一个有用的东西还有很多需要考虑的因素。答案。
答案 4 :(得分:1)
如上所述,复杂性仍然存在。
但在现实世界中,我们无法预测哪个版本运行得更快。以下是扮演角色的因素,巨大的因素:
(注意:在他们所有人身上,都有达摩克利斯的错误预测之剑;所有这些都是可以摧毁的并且可以转让)
特别是最后一个因素使得有时无法为性能依赖于特定高速缓存大小的代码编译一个真正的代码。有些应用程序在具有巨大缓存的CPU上运行速度更快,而在小缓存上运行速度较慢,而对于其他一些应用程序则相反。
解决方案:
尝试适应目标的软件总是一个好主意,理想情况下不会牺牲代码质量。在进行手动优化之前,无论是微观的还是宏观的,测量现实世界的运行,然后才进行优化。
文献: * Agner Fog's Guides * Intel's Guides
答案 5 :(得分:0)
您注意到通过创建第二个循环会产生一些性能开销是正确的。因此,它不能“同样快”;因为这个开销很小,仍然是开销。
我不会试图巧妙地谈论应该如何构建碰撞系统,但是如果你想要优化性能,最好避免构建不必要的控制结构,如果你可以在不拉扯头发的情况下进行管理。
请记住,过早优化是您可以做的最糟糕的事情之一。在我看来,当您遇到性能问题时,请考虑优化。