List<T> 填充集合性能
Posted
技术标签:
【中文标题】List<T> 填充集合性能【英文标题】:List<T> fill collection performance 【发布时间】:2009-10-14 21:55:37 【问题描述】:我在填写类型列表时遇到了性能问题。以下是我的简化代码:
public static List<Product> GetProducts()
List<Product> products = new List<Product>();
using (DbQuery query = new DbQuery()) //this is database access class
query.CommandText = "SELECT ProdID, ProdName,Price FROM SomeTable " ;+
using (IDataReader rdr = query.ExecuteReader())
while (rdr.Read())
Product prd = new Product();
prd.ProdID = DbQuery.ReadInt ( rdr, "ProdID", -1 );
prd.ProdName = DbQuery.ReadString(rdr, "ProdName", "");
prd.Price = DbQuery.ReadDouble(rdr, "Price", 0);
products.Add(prd);
我也有简单的 struct Product (ProdID, ProdName,Price)。
我的问题是执行 GetProducts() 需要 4 秒。该查询返回大约 600 条记录,返回结果需要几毫秒,所以我确信填充产品集合需要所有这些时间。我在这里做一些低效的事情吗?请帮忙。 谢谢, 格尔达
【问题讨论】:
【参考方案1】:您是否尝试在要过滤的字段上放置索引?与没有索引相比,这肯定会加快您的查询速度。
【讨论】:
【参考方案2】:列表插入非常快。这里一定有其他事情发生。尝试在有和没有 products.Add(prd)
注释掉的情况下计时。我怀疑你会发现它们几乎相同。
这是我解决此问题的方法:一次注释一行,直到您看到性能大幅提升 - 然后您就会找到罪魁祸首。
另一件需要注意的事情:数据库性能不是一成不变的。例如,第一次执行需要 4 秒的查询,第二次执行可能只需要 100 毫秒,因为所有数据都缓存到 RAM 中,因此第二次不需要进行物理 I/O。由于 SQL 会引发很多事情,因此对数据库的第一次查询会很慢。我的建议:总是从热缓存开始,这意味着运行一次代码然后再次运行它,并且只考虑第二次计时。更好的是,运行代码 10 次,然后计时 10 次,然后丢弃前 10 次,取第二次的平均值。
【讨论】:
【参考方案3】:正如贾斯汀建议的那样,我个人会开始注释掉代码部分,直到找到导致瓶颈的原因。例如,我可能首先让例程只运行以数据库为中心的代码:
public static List<Product> GetProducts()
List<Product> products = new List<Product>();
using (DbQuery query = new DbQuery())
query.CommandText = "SELECT ProdID, ProdName,Price FROM SomeTable ";
using (IDataReader rdr = query.ExecuteReader())
while (rdr.Read())
//Product prd = new Product();
//prd.ProdID = DbQuery.ReadInt(rdr, "ProdID", -1);
//prd.ProdName = DbQuery.ReadString(rdr, "ProdName", "");
//prd.Price = DbQuery.ReadDouble(rdr, "Price", 0);
//products.Add(prd);
return products;
通过注释掉创建产品对象并将它们添加到列表中的部分,我可以看到数据库相关代码的运行速度。如果运行速度快于 4 秒,那么我知道这与 Product 对象创建和/或对 DBQuery 的调用有关,这些调用需要很长时间才能完成。
这是反复试验,但由于此例程非常简单,因此进行此类分析应该不会花费很长时间。
【讨论】:
【参考方案4】:如果这是您的瓶颈,我会感到惊讶。我会尝试制作一个具有模拟数据库连接的小测试应用程序。
如果您可以预先确定列表的大小,通常可以做得更好。如果查询有一个合理的最小大小,或者如果您有其他方式知道(或合理猜测)一个好的初始大小,您可能会得到微小的提升。
【讨论】:
【参考方案5】:从它的声音来看,这一定是数据库性能或延迟问题(如果是远程连接)。
【讨论】:
以上是关于List<T> 填充集合性能的主要内容,如果未能解决你的问题,请参考以下文章