最近,我不得不对存储在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的理解是正确的)但它看起来并不像......

我是从内存中编写代码所以有些东西可能不是“语法正确”。

有帮助吗?

解决方案

通过 Reflector ,DataRow [" ColumnName"]的步骤如下:

  1. 从ColumnName获取DataColumn。使用行的DataColumnCollection [" ColumnName"]。在内部,DataColumnCollection将其DataColumns存储在Hastable中。 O(1)
  2. 获取DataRow的行索引。索引存储在内部成员中。 O(1)
  3. 使用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)

  4. 总的来说,你是O(1),但这并不意味着在操作过程中散列和函数调用是免费的。它只是意味着随着DataRows或DataColumns的数量增加而不会花费更多。

    有趣的是DataStorage将数组用于值。无法想象在添加或删除行时很容易重建。

其他提示

实际上,建议在引用列时使用整数,这可以在性能方面提高很多。为了使事情易于管理,您可以声明常量整数。所以,不是你做了什么,你可以做

const int SomeTable_SomeColumn = 0;

DataTable dt = new DataTable();
if(dt.Columns.Contains(SomeTable_SomeColumn))
{
    object o = dt.Rows[0][SomeTable_SomeColumn];
}

我想任何查找都是O(n),因为我认为它们不会使用任何类型的哈希表,但实际上会使用更多的数组来查找行和列。

实际上,我相信列名存储在Hashtable中。对于区分大小写的查找,应该是O(1)或常量查找。如果它必须查看每个,那么当然它将是O(n)。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top