我有两个自定义类Grid
和Element
:
public class Grid
{
public double ID { get; set; }
public double X { get; set; }
public double Y { get; set; }
public double Z { get; set; }
public MyClass MoreProperties {get; set;}
public Grid(int id, double x, double y, double z)
{
this.ID = id;
this.X = x;
this.Y = y;
this.Z = z;
}
}
Element
:
public abstract class Element
{
public int ID { get; set; }
public int NumberOfGrids { get; set; }
public List<Grid> Grids { get; set; } //4 Grids in this case
public Element()
{
Grids = new List<Grid>();
}
}
为了说明这种情况,请看这张照片:
有一个名为Data
的类的容器:
class Data : ModelBase
{
public List<Grid> Grids{ get; set; }
public List<Element> Elements { get; set; }
}
我读过有大量数据的文本文件:网格和元素 这是网格的格式(简化):
GRID ID X Y Z
对于元素
ELEMENT ID GRID1 GRID2 GRID3 GRID4
因此,GRID
条目提供网格点的位置和ID,ELEMENT
提供该元素的网格ID及其自己的ID。
我想要的是为每个元素关联所有4个网格,这样我将拥有元素对象中每个网格的坐标
。为此,我读了两次文件(因为元素条目出现在网格之前并简化了一些事情):我第一次阅读它时填写了Grids
列表(来自Data类)。
我第二次填写Elements
列表并做更多的事情。当我填写Elements
列表时,我只能填写相关Grid
的ID。
如果您已阅读此处,我们会将此类数据包含两个Grid
和Elements
列表。
对于这种关联,我提出了这种方法:
public void AsociateGridsToElements()
{
foreach (Element elem in Elements)
{
for (int i = 0; i < elem.Grids.Count; i++)
{
elem.Grids[i] = Grids.Where(g => g.ID == elem.Grids[i].ID).FirstOrDefault();
}
}
}
它循环遍历每个元素,然后遍历该元素的每个网格(在本例中为4),然后它在整个网格列表中查找哪些网格具有相同的ID。当它找到第一个时,它会分配该网格,这样元素就有了“完整”Grid
对象,而不是只填充了ID的对象(因为这是我读取文件时唯一能得到的东西)
问题出在这里:这些文件相当大:大约20 000个网格点和10 000个元素,如果我为每个元素循环查看每次整个网格集合(4次)它是:20 000 x 10 000 = 2亿次操作。所以计算机无法处理它,我认为必须改进它。
有人可以提示或帮助我优化这个问题吗?谢谢。
答案 0 :(得分:6)
如果保证每个Grid
对象的ID都是唯一的,我首先要创建一个Grid
个对象的字典,其中ID作为字典中的键。然后在枚举元素期间查找填充的Grid
只需要字典查找而不是网格列表的新枚举。
public void AsociateGridsToElements()
{
var gridLookup = Grids.ToDictionary(grid => grid.ID);
foreach (Element elem in Elements)
{
for (int i = 0; i < elem.Grids.Count; i++)
{
Grid fullyPopulatedGrid;
if (gridLookup.TryGetValue(elem.Grids[i].ID, out fullyPopulatedGrid))
{
elem.Grids[i] = fullyPopulatedGrid;
}
else
{
// Unable to locate Grid Element
}
}
}
}
在这种情况下,创建字典查找可以显着提高性能,因为它可以防止对网格列表进行额外的枚举。
上面的代码执行以下操作(根据您的估算):
Grid
个项目,并为每个项目创建一个键值对。 (约20,000步)Element
项(约10,000步)Grid
中的每个部分Element
(称之为4个步骤)Grid
(1哈希查找)此处的总步数约为20,000 +(10,000 * 4)* 2(每个元素/网格1个哈希查找)= 100,000步
您的原始代码执行以下操作:
Element
项(约10,000步)Grid
中的每个部分Element
(称之为4个步骤)Grid
项(约20,000步)以查找第一个匹配项(这需要为每个元素/网格组合单独迭代)此处的总步数约为10,000 * 4 * 20,000 = 800,000,000步