2012-12-19 61 views
0

好,我想创建一个对象数组foo[],其中对于Foo构造是转换对象层次结构,以对象数组

public Foo(string name, string discription){} 

我有具有结构的数据库对象(未incuding存储过程,函数或意见为简单起见)像

public class Database 
{ 
    public string name { get; set; } 
    public string filename { get; set; } 
    public List<Table> tables { get; set; } 

    public Database(string name, string filename) 
    { 
     this.name = name; 
     this.filename = filename; 
    } 
} 

protected internal class Table 
{ 
    public string name { get; set; } 
    public List<Column> columns { get; set;} 

    public Table(string name, List<Column> columns) 
    { 
     this.name = name; 
     this.columns = columns; 
    } 
} 

protected internal class Column 
{ 
    public string name { get; set; } 
    public string type { get; set; } 

    public Column(string name, string type, int maxLength, 
        bool isNullable) 
    { 
     this.name = name; 
     this.type = type; 
    } 
} 

我想知道添加ColumnTable信息到Foo[]对象数组的最快方法?

显然,我可以做

List<Foo> fooList = new List<Foo>(); 
foreach (Table t in database.tables) 
{ 
    fooList.Add(new Foo(t.Name, "Some Description")); 
    foreach (Column c in t.columns) 
     fooList.Add(new Foo(c.Name, "Some Description")); 
} 
Foo[] fooArr = fooList.ToArray<Foo>(); 

但有一个更快的方法?很明显LINQ对于执行simalar操作的查询可能会比较慢,但我在意这里关于速度的所有信息,所以我们将不胜感激。也许使用HashSet将是不错的选择......

感谢您的时间。

+1

考虑从列表<>属性中删除setter。你并不需要它们(移除setter将不会使对象只能读取对象的引用)。 –

+0

是什么让你认为LINQ会变慢? –

+0

最后,为什么你需要一个数组呢?为什么,确切地说,是一个列表不够好?这个问题的答案可能会影响如何解决问题的建议。 –

回答

2

我要说改变你的foreach循环的循环,因为这里In .NET, which loop runs faster, 'for' or 'foreach'? 数据结构网络化明智的,你做的讨论需要可变结构,除非您确切知道将要插入fooList的记录数量,则可以使用Array而不是列表。根据foreach与for-loop问题的答案,假设它是正确的,List上的循环比List上的foreach循环便宜2倍以上,而Looping on array比List上的循环便宜2倍左右。

SO 2的改进是:

  1. 变化的foreach为

  2. 使用LINQ来计算阵列 按照@Tim Schmelter的长度,以及改变清单阵列

+0

感谢您的回答。切换到for循环是一个好主意。感谢您的链接...一切顺利。 – MoonKnight

2

你可以用正确的尺寸初始化数组,只使用它,而后备名单:

int size = db.tables.Sum(t => t.columns.Count + 1); 
Foo[] fooArr = new Foo[size]; 
int currentSize = 0; 
foreach (var tbl in db.tables) 
{ 
    fooArr[currentSize++] = new Foo(tbl.Name, "Some Discription"); 
    foreach(var c in tbl.columns) 
     fooArr[currentSize++] = new Foo(c.Name, "Some Discription"); 
} 
+0

谢谢,这是一个好主意。我想我必须进行测试才能真正看到我会收到什么样的好处。感谢您的时间...... – MoonKnight

+1

@Killercam:您至少有机会减少内存消耗和可能发生的'OutOfMemoryException'。你的清单已经使用了两倍的内存。还要记住'List '使用加倍算法;如果你通过'Add'喂食物品(不先分配所有的空间),它总会尝试将容量加倍。如果列表已经很大(比如1 GB),那么下一个超过后备数组内部容量的Add将分配2GB。 –