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; } }
元件:
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个网格,这样我将在元素对象内部拥有每个网格的坐标.
为此我读了两次文件(因为元素条目出现在网格之前并简化了一些事情):第一次读到它时我填写了网格列表(来自Data类).
我第二次填写元素列表并做更多的事情.当我填充元素列表时,我只能填充相关网格的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 = 200 000 000次行动.所以计算机无法处理它,我认为它必须得到改进.
任何人都可以提示或帮助我优化这个问题吗?谢谢.
解决方法
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 } } } }
在这种情况下,创建字典查找可以显着提高性能,因为它可以防止格网列表的其他枚举.
上面的代码执行以下操作(根据您的估算):
>枚举所有网格项并为每个项创建一个键值对. (约20,000步)
>枚举所有元素项(约10,000步)
>枚举该元素中的每个部分网格(称之为4个步骤)
>在字典上执行查找以找到正确填充的网格(1哈希查找)
这里的总步数约为20,000(10,000 * 4)* 2(每个元素/网格1个哈希查找)= 100,000步
您的原始代码执行以下操作:
>枚举所有元素项(约10,000步)
>枚举该元素中的每个部分网格(称之为4个步骤)
>枚举所有填充的网格项(约20,000步)以查找第一个匹配(这需要为每个元素/网格组合单独迭代)
这里的总步数约为10,000 * 4 * 20,000 = 800,000,000步