我一直在设计一个基于组件的游戏库,其总体目的是用C ++编写它(因为这是我的专长),Ogre3D作为后端。现在我已经准备好编写一些代码,我认为在XNA4.0框架下测试我的框架会更快(获得结果/编写编辑器等更快一些)。然而,虽然我不是C ++或C#的新手,但是当我以“XNA”的方式做事时,我是有点新手,可以这么说,所以我之前有一些问题开始敲定代码:
我读到了使用数组而不是集合以避免性能命中,然后还读到这不完全正确,如果你枚举一个具体的List<>
集合(而不是IEnumerable<>
),枚举器是一个值类型,用于每次迭代,并且这里没有任何GC担心。有问题的文章早在2007年。这是否成立,或者您是否经历过XNA开发人员对此有真实的陷阱?理想情况下,在做太多事情之前,我想先选择一条路线。
如果数组确实是真正的方法,没有问题,我假设在调整数组大小时,你用新的空间复制旧的数组?或者这是不是标志?您是否尝试永远不会调整阵列的大小?如果是这种情况,那么GC是否会为旧版本启动,或者是无关紧要的打击?
由于引擎是为C ++设计的,因此该设计允许使用lambdas和delegates。一种设计使用fastdelegate
库,这是在C ++中使用委托的最快方式。一种更灵活但稍慢的方法(虽然在C ++世界中几乎不可察觉)是使用C ++ 0x lambdas和std::function
。理想情况下,我想在XNA中做类似的事情,并允许使用代理。委托人的使用是否会导致任何与绩效有关的重大问题?
如果对代表有性能方面的考虑,那么:
之间存在差异public void myDelegate(int a, int b);
private void myFunction(int a, int b)
{
}
event myDelegate myEvent;
myEvent += myFunction;
VS
public void myDelegate(int a, int b);
event myDelegate myEvent;
myEvent += (int a, int b) => { /* ... */ };
对不起,如果我有点胡扯,我更愿意明白我的问题。 :)
提前致谢!
答案 0 :(得分:5)
基本上,C#中唯一需要注意的主要性能问题是垃圾收集器,它与您在C ++中必须注意的不同。只是不要在你的主游戏循环中分配内存,你会没事的。 Here is a blog post that goes into detail
现在回答你的问题:
1)如果框架集合迭代器可以实现为值类型(不创建垃圾),那么它通常(总是?)已经存在。您可以安全地使用foreach
,例如List<>
。
您可以使用CLR Profiler验证是否在主循环中进行分配。
2)使用List
代替数组。他们会为你处理调整大小。在开始游戏之前,您应该使用Capacity
属性预先分配足够的空间,以避免GC问题。使用数组你只需要自己实现所有这些功能 - 丑陋!
GC启动分配(而不是当内存变为空闲时)。在Xbox 360上,它每1MB分配一次并且非常慢。在Windows上它有点复杂 - 但也没有对性能产生如此巨大的影响。
3) C#代表非常快。并且比大多数人预期的要快。它们与接口上的方法调用大致相同。 Here和here是提供有关C#中委托效果的更多详细信息的问题。
我不知道它们与C ++选项的比较。你必须测量它。
4)不,我很确定这段代码会产生相同的IL。您可以将其拆解并检查或分析它。
我可能会添加 - 不检查自己 - 如果您不需要event myDelegate
的所有魔法,我怀疑拥有myDelegate
会比普通event
慢。