最近,我不得不对存储在DataSet中的数据做一些非常重要的处理。它足够重,我最终使用工具来帮助识别代码中的一些瓶颈。当我分析瓶颈时,我注意到尽管DataSet查找速度并不是非常慢(它们不是瓶颈),但它比我预期的要慢。我总是假设DataSet使用某种HashTable样式实现,这将使查找O(1)(或者至少是我认为的HashTables)。我的查找速度似乎明显慢于此。
我想知道是否有人对.NET的DataSet类的实现有所了解是否愿意分享他们所知道的内容。
如果我这样做:
DataTable dt = new DataTable();
if(dt.Columns.Contains("SomeColumn"))
{
object o = dt.Rows[0]["SomeColumn"];
}
查询时间对Contains(...)
方法的查询时间有多快,以及检索要存储在Object o
中的值?我会认为它像HashTable一样非常快(假设我对HashTables的理解是正确的)但它看起来并不像......
我从内存中编写了这段代码,所以有些东西可能不是“语法正确”。
答案 0 :(得分:3)
实际上,建议在引用列时使用整数,这可以在性能方面提高很多。为了使事情易于管理,您可以声明常量整数。所以,不是你做了什么,你可以做
const int SomeTable_SomeColumn = 0;
DataTable dt = new DataTable();
if(dt.Columns.Contains(SomeTable_SomeColumn))
{
object o = dt.Rows[0][SomeTable_SomeColumn];
}
答案 1 :(得分:2)
通过Reflector DataRow [“ColumnName”]的步骤为:
使用DataColumn [index]获取索引处的DataColumn值。 DataColumn将其数据存储在System.Data.Common.DataStorage(内部,抽象)成员中:
return dataColumnInstance._storage.Get(recordIndex);
示例具体实现是System.Data.Common.StringStorage(内部,密封)。 StringStorage(以及我检查过的其他具体DataStorage)将它们的值存储在一个数组中。 Get(recordIndex)只是抓取recordIndex中value数组中的对象。 O(1)
总的来说,你是O(1),但这并不意味着在操作过程中散列和函数调用是免费的。它只是意味着随着DataRows或DataColumns的数量增加而不会花费更多。
有趣的是DataStorage将数组用于值。无法想象在添加或删除行时很容易重建。
答案 2 :(得分:0)
我想任何查找都是O(n),因为我认为它们不会使用任何类型的哈希表,但实际上会使用更多的数组来查找行和列。
答案 3 :(得分:0)
实际上,我相信列名存储在Hashtable中。对于区分大小写的查找,应该是O(1)或常量查找。如果它必须查看每个,那么当然它将是O(n)。