为什么我的C#嵌套for循环速度慢?
我正在创建一个游戏作为一个学校项目,并认为这将是一个好主意,使用颜色映射创建水平,但我使用的方法是非常缓慢的,因为某些原因为什么我的C#嵌套for循环速度慢?,c#,performance,xna,nested-loops,monogame,C#,Performance,Xna,Nested Loops,Monogame,我正在创建一个游戏作为一个学校项目,并认为这将是一个好主意,使用颜色映射创建水平,但我使用的方法是非常缓慢的,因为某些原因 public List<Entity> LoadLevel(Level level) { List<Entity> ents = new List<Entity>(); Color[] clrs = new Color[level.getColorMap.Height*level.g
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;
}
公共列表加载级别(级别)
{
List ents=新列表();
Color[]clrs=new Color[level.getColorMap.Height*level.getColorMap.Width];
level.getColorMap.GetData(clrs);
对于(int x=0;x
我在LoadContent()中调用这个函数,执行起来大约需要半分钟,为什么这么慢?我对编码风格有一些说明。很可能这不是你问题的原因,但最好早点知道。一般来说,你应该避免重复和不必要的工作。我甚至不会称之为优化,我会称之为规则。这应该是您编写代码的方式
- 如果
需要一段时间怎么办?你一遍又一遍地叫它,即使你不需要这样做。你一般不应该相信这样一个事实,那就是房产很便宜。打一次电话,记住结果level.getColorMap
相当快,但不是免费的。如果你不需要它,就不要叫它。建立新地形并记住指向它的指针ents.Last()
- 每个循环中新的
都不好。不要把吊环当作理所当然的事。最有可能的是,即使您实际需要三个颜色对象,您也会构造12000000个颜色对象颜色(0,0,0)
- 你的代码也有很多两面性。通常,在复制和粘贴代码之前要三思而后行。干的
- 循环顺序不好。从一行跳到另一行会破坏缓存的位置。您应该处理整行,然后转到下一行
- 当你只需要加法时,避免乘法
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;
}
public void AddTerrain(列表元素、整数选择器、整数x、整数y)
{
地形牛顿=新地形(新矢量2(x,y));
添加(牛顿);
var animation=newT.animation;
setImageIndex(选择器);
如果(选择器>0)
{
动画设定速度(69);
}
动画。播放();
}
公共列表加载级别(级别)
{
List ents=新列表();
var colorMap=level.getColorMap;
int colorMapWidth=colorMap.Width;
int colorMapHeight=colorMap.Height;
颜色[]clrs=新颜色[colorMapWidth*colorMapHeight];
颜色[]颜色=新颜色[]{新颜色(0,0,0),新颜色(6,6,6),新颜色(9,9,9)};
colorMap.GetData(clrs);
int-ci=0;
对于(int y=0;y
(代表OP发布)
问题实际上出在terrainobject的构造函数中,用于创建其碰撞器的函数似乎优化得非常糟糕,感谢您的帮助 这更适合于
level.getColorMap.Height
和level.getColorMap.Width
?它们都是2048大。我们不知道所有这些动画方法都做什么。注释所有以“ents”开头的行。如果有帮助,问题不在这段代码中。@AntonínLejsek可能在这段代码中<例如,code>getColorMap可能正在从磁盘加载彩色地图。您是对的,“成本”是这段代码的外部因素,但它仍然是可以改进的。在任何情况下,持续访问level.getColorMap
和level.getColorMap.Width
而不是将其存储在局部变量中都有点像是一种味道。另外,缺少else if
而不是冗余计算。非常好的建议。反转x和y循环可能是最大的变化。缓存是一件非常重要的事情。