如何在C#中有效地处理许多更新对象?

Bob*_*Bob 8 c# xna garbage-collection

我正在使用C#和XNA开发2D头顶射击游戏.我有一个我称之为"子弹"的类,需要在每一秒钟内更新许多这些实例.

我这样做的第一种方法是拥有一个通用的子弹列表,并根据需要简单地移除和添加新的子弹.但是在这样做的过程中,GC经常出现,我的游戏有一些周期性的生涩延迟.(很多代码被删除了,但只想展示一个简单的代码片段)

if (triggerButton)
{
    bullets.Add(new bullet());
}
if (bulletDestroyed)
{
    bullets.Remove(bullet);
}
Run Code Online (Sandbox Code Playgroud)

我的第二个也是当前的尝试是有一个单独的通用Stack子弹,当我完成一个子弹时我会推动它,如果堆栈中有任何东西,当我需要一个新子弹时弹出子弹.如果堆栈中没有任何内容,那么我将新的项目符号添加到列表中.它似乎减少了生涩的滞后,但又一次,有时还会出现一些生涩的滞后(尽管我不知道它是否相关).

if (triggerButton)
{
    if (bulletStack.Count > 0)
    {
        bullet temp = bulletStack.Pop();
        temp.resetPosition();
        bullets.Add(temp);
    }
    else
    {
        bullets.Add(new bullet());
    }
}
if (bulletDestroyed)
{
    bulletStack.Push(bullet);
    bullets.Remove(bullet);
}
Run Code Online (Sandbox Code Playgroud)

所以,我知道过早的优化是所有邪恶的根源,但这是非常明显的低效率,我可以提前赶上(这是在甚至不必担心敌人的子弹充满屏幕之前).所以我的问题是:将未使用的对象推送到堆栈会调用垃圾收集吗?参考文件是保持活着还是被破坏的对象?有没有更好的方法来处理更新许多不同的对象?例如,我是否太过花哨?如果只是遍历列表并找到一个未使用的子弹就可以了吗?

Ree*_*sey 11

这里有很多问题,这很难说.

首先,是bullet结构还是类?如果bullet是一个类,那么无论何时构造一个类,然后将其unroot(让它超出范围或将其设置为null),您将要添加GC需要收集的内容.

如果您要制作其中的许多内容,并在每一帧中更新它们,您可能需要考虑使用List<bullet>with bullet作为结构,并且预先分配List(生成它的大小足以容纳所有的子弹,所以它没有被重新创建,因为你打电话List.Add).这将极大地帮助GC压力.

还有,因为我需要咆哮:

所以,我知道过早优化是所有邪恶的根源,但这是非常明显的低效率

永远不要害怕优化你知道导致问题的例程.如果您发现性能问题(即:滞后),则不再是过早优化.是的,您不希望优化每行代码,但您确实需要优化代码,尤其是当您发现真正的性能问题时.一旦发现问题就优化它比稍后尝试优化它更容易,因为在添加许多使用您的bullet类的其他代码之前,所需的任何设计更改都将更容易实现.