这些C#功能的性能影响是什么?

时间:2011-10-16 08:46:20

标签: xna c#

我一直在设计一个基于组件的游戏库,其总体目的是用C ++编写它(因为这是我的专长),Ogre3D作为后端。现在我已经准备好编写一些代码,我认为在XNA4.0框架下测试我的框架会更快(获得结果/编写编辑器等更快一些)。然而,虽然我不是C ++或C#的新手,但是当我以“XNA”的方式做事时,我有点新手,可以这么说,所以我之前有一些问题开始敲定代码:

  1. 我读到了使用数组而不是集合以避免性能命中,然后还读到这不完全正确,如果你枚举一个具体的List<>集合(而不是IEnumerable<>),枚举器是一个值类型,用于每次迭代,并且这里没有任何GC担心。有问题的文章早在2007年。这是否成立,或者您是否经历过XNA开发人员对此有真实的陷阱?理想情况下,在做太多事情之前,我想先选择一条路线。

  2. 如果数组确实是真正的方法,没有问题,我假设在调整数组大小时,你用新的空间复制旧的数组?或者这是不是标志?您是否尝试永远不会调整阵列的大小?如果是这种情况,那么GC是否会为旧版本启动,或者是无关紧要的打击?

  3. 由于引擎是为C ++设计的,因此该设计允许使用lambdas和delegates。一种设计使用fastdelegate库,这是在C ++中使用委托的最快方式。一种更灵活但稍慢的方法(虽然在C ++世界中几乎不可察觉)是使用C ++ 0x lambdas和std::function。理想情况下,我想在XNA中做类似的事情,并允许使用代理。委托人的使用是否会导致任何与绩效有关的重大问题?

  4. 如果对代表有性能方面的考虑,那么:

    之间存在差异
    public void myDelegate(int a, int b);
    private void myFunction(int a, int b)
    {
    }
    
    event myDelegate myEvent;
    
    myEvent += myFunction;
    
  5. VS

        public void myDelegate(int a, int b);
    
        event myDelegate myEvent;
    
        myEvent += (int a, int b) => { /* ... */ };
    

    对不起,如果我有点胡扯,我更愿意明白我的问题。 :)

    提前致谢!

1 个答案:

答案 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#代表非常快。并且比大多数人预期的要快。它们与接口上的方法调用大致相同。 Herehere是提供有关C#中委托效果的更多详细信息的问题。

我不知道它们与C ++选项的比较。你必须测量它。

4)不,我很确定这段代码会产生相同的IL。您可以将其拆解并检查或分析它。

我可能会添加 - 不检查自己 - 如果您不需要event myDelegate的所有魔法,我怀疑拥有myDelegate会比普通event慢。