首页 > 解决方案 > 在大型 Unity/C# 游戏中过滤通用集合的理想性能

问题描述

我正在使用 Unity/C# 开发一款商业游戏,并且正在审查并熟悉代码。我开始对此感到疑惑,因为在很多情况下,您会持有一个充满诸如 GameObjects、Components 或 ScriptableObjects 之类的列表……例如,您可能在 RTS 游戏类中有这样的字段:

protected List<Unit> allUnits = new List<Unit>();

现在,假设在运行时触发了一个事件,您需要在其中循环allUnits并操作某些事件,或者只选择您想要的某些事件,甚至确定满足某个条件的事件的数量。请容忍我这个人为的例子,但 3 种标准方法是 for-loop、for-each 或 Linq 扩展方法/查询语句。假设我想找到所有未受重伤或死亡且弹药不足的单位。我可以使用以下方法来处理这个问题:

        for ( int i = 0; i < allUnits.Count; i++ ) {

            var next = allUnits[i];

            if ( next.IsDead ) continue;
            if ( next.IsCriticallyWounded ) continue;
            if ( next.AmmoCount >= Magazine.MaxCapacity * 3 ) continue;
            else
                unitsLowOnAmmo.Add( next );
        }

您可以在循环中使用相同的逻辑foreach( var next in allUnits ),所以我不会再重复相同的代码。但是另一种方法是这样的,使用 Linq 扩展:

        unitsLowOnAmmo = allUnits.Where( u => 
                                        !u.IsDead && 
                                        !u.IsCriticallyWounded && 
                                        !u.AmmoCount >= Magazine.MaxCapacity * 3 ).ToList();

您还可以使用此语法查找 AI 控制下的所有内容,例如:

        var aiUnits = (from Unit u in allUnits
                      where u.AIControlled
                      select u).ToList();

在另一种情况下,您可能需要找到满足一组条件的单位总数,例如我想找到所有受重伤的 AI 控制单位,以便他们可以派出医务人员或尝试将他们带到安全的地方野战医院。所以我可以通过使用累加器来做到这一点,比如for ( int i = 0, count = 0; i < allUnits.Count; i++ )然后检查错误的条件和continue;循环,否则如果它通过过滤器则让它落入一条count++;语句。或者,显然,我可以使用int count = List<T>.Count( u => cond1 && cond2 );...

现在,很明显,Linq 的东西更干净,更有表现力,代码也更容易阅读和维护,但我们都听过聪明的 C# 大师说“Linq 性能很差!永远不要使用 Linq!” 这些年来。而且我想知道对 Linq 的偏见到底是真是假,以及这些不同方法的表现如何真正不同并在“现场”表现。我正在处理一个非常大的项目,其中包含大约 24GB 的资产、代码和数据,它非常复杂,并且类中有很多 List 实例,用于存储经常需要迭代、过滤或计数的各种内容。在某些情况下,它是逐帧的,而在其他情况下,它是在特定的时间量之后或在事件或方法调用之后。

任何人都可以对性能比较有所了解,以及最好的方法是循环遍历集合以最高效的方式过滤、选择和计数它们吗?也许还有一种我在这里没有提到的更好的方法可能会更好?我已经阅读了这里(和其他网站)上的一些文章,这些文章并没有详细回答这个问题,让我对此感到满意。在离开一段时间后,我也刚刚了解了 C# 和 .NET 中的所有最新内容,我不确定框架(或语言)是否有任何可能完全改变事情的变化人们过去常说 Linq。我听说 Microsoft 吹嘘在 .NET 的许多领域都有性能改进,我想知道这些收益是否与这种情况有关。

标签: c#performancelinqunity3dgenerics

解决方案


推荐阅读