为什么我的C#嵌套for loop慢?

时间:2017-03-26 23:12:15

标签: c# performance xna nested-loops monogame

我正在创建一个游戏作为学校项目,并认为使用色彩映射进行关卡创建是一个好主意,但是由于某种原因,我使用的方法非常慢。 / p>

        public List<Entity> LoadLevel(Level level)
    {
        List<Entity> ents = new List<Entity>();
        Color[] clrs = new Color[level.getColorMap.Height*level.getColorMap.Width];
        level.getColorMap.GetData(clrs);
        for (int x = 0; x < level.getColorMap.Width; x++)
        {
            for (int y = 0; y < level.getColorMap.Height; y++)
            {
                if (clrs[x + y * level.getColorMap.Width] == new Color(0, 0, 0))
                {
                    ents.Add(new Terrain(new Vector2(x, y)));
                    ents.Last().Animation.setImageIndex(0);
                    ents.Last().Animation.Play();
                }
                if (clrs[x + y * level.getColorMap.Width] == new Color(6, 6, 6))
                {
                    ents.Add(new Terrain(new Vector2(x, y)));
                    ents.Last().Animation.setImageIndex(6);
                    ents.Last().Animation.setSpeed(69);
                    ents.Last().Animation.Play();
                }
                if (clrs[x + y * level.getColorMap.Width] == new Color(9, 9, 9))
                {
                    ents.Add(new Terrain(new Vector2(x, y)));
                    ents.Last().Animation.setImageIndex(9);
                    ents.Last().Animation.setSpeed(69);
                    ents.Last().Animation.Play();
                }
            }
        }
        return ents;


    }

我在LoadContent()中调用此函数,执行大约需要半分钟,为什么这么慢?

2 个答案:

答案 0 :(得分:0)

我对编码风格有一些注意事项。最有可能的原因不是你的问题,而是更好地早知道。一般来说,你应该避免做重复和不必要的工作。我甚至不称它为优化,我会称之为规则。这应该是你总是编码的方式。

  • 如果level.getColorMap需要一段时间怎么办?即使您不需要这样做,也可以反复调用它。你通常不应该依赖这个事实,即财产便宜。叫它一次并记住它的结果。

  • ents.Last()非常快,但不是免费的。如果你不需要它,请不要打电话。建立新的地形并记住指向它的指针。

  • 每个循环中的新Color(0, 0, 0)都不好。不要将循环吊装视为已批准。很可能你甚至在实际需要三个时就会构造12000000个颜色对象。

  • 您的代码也有很多不完整之处。通常,在复制和粘贴代码之前请三思而后行。 DRY

  • 循环顺序不好。您从一行跳到另一行破坏缓存局部性。您应该处理整行,然后转到下一行。

  • 当您只需要添加时,请避免乘法。

改进的例子:

public void AddTerrain(List<Entity> ents, int selector, int x, int y)
{
    Terrain newT = new Terrain(new Vector2(x, y));
    ents.Add(newT);
    var animation = newT.Animation;
    animation.setImageIndex(selector);
    if (selector > 0)
    {
        animation.setSpeed(69);
    }
    animation.Play();
}



public List<Entity> LoadLevel(Level level)
{
    List<Entity> ents = new List<Entity>();
    var colorMap = level.getColorMap;
    int colorMapWidth = colorMap.Width;
    int colorMapHeight = colorMap.Height;
    Color[] clrs = new Color[colorMapWidth * colorMapHeight];
    Color[] colors = new Color[] { new Color(0, 0, 0), new Color(6, 6, 6), new Color(9, 9, 9) };
    colorMap.GetData(clrs);

    int ci = 0;
    for (int y = 0; y < colorMapHeight; y++)
    {
        for (int x = 0; x < colorMapWidth; x++)
        {
            Color c = clrs[ci++];
            for (int i = 0; i < colors.Length; ++i)
            {
                if (c == colors[i])
                {
                    AddTerrain(ents, c.R, x, y);
                    break;
                }
            }
        }
    }

    return ents;
}

答案 1 :(得分:0)

(代表OP发布)

问题实际上是在地形对象的构造函数中,由于帮助,创建其对撞机的功能显然非常优化!