6

最近、DataSet に格納されたデータを使用して、非常に処理量の多い作業を行う必要がありました。コードのボトルネックを特定するのに役立つツールを使用することになったほど重いものでした。ボトルネックを分析していたとき、DataSet ルックアップはそれほど遅くはありませんでしたが (ボトルネックではありませんでした)、予想よりも遅いことに気付きました。私は常に、DataSets がルックアップを O(1) にする何らかの HashTable スタイルの実装を使用していると想定していました (または、少なくともそれが HashTables であると私が考えるものです)。私のルックアップの速度は、これよりもかなり遅いように見えました。

.NET の DataSet クラスの実装について何か知っている人が、知っていることを共有してくれるかどうか疑問に思っていました。

私がこのようなことをすると:

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

メソッドのルックアップ時間と、Contains(...)格納する値を取得する時間はどれくらいかかりますObject oか? HashTableのように非常に高速だと思っていたでしょう(HashTableについて理解していることが正しいと仮定して)が、そうではないようです...

私はそのコードを記憶から書いたので、「構文的に正しくない」ものもあるかもしれません。

4

4 に答える 4

3

実際には、列を参照するときに整数を使用することをお勧めします。これにより、パフォーマンスが大幅に向上する可能性があります。物事を管理しやすくするために、定数整数を宣言することができます。だからあなたがしたことの代わりに、あなたはすることができます

const int SomeTable_SomeColumn = 0;

DataTable dt = new DataTable();
if(dt.Columns.Contains(SomeTable_SomeColumn))
{
    object o = dt.Rows[0][SomeTable_SomeColumn];
}
于 2008-09-28T05:56:09.747 に答える
2

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 の値配列内のオブジェクトを取得するだけです。O(1)

したがって、全体としては O(1) ですが、それは操作中のハッシュと関数呼び出しにコストがかからないという意味ではありません。これは、DataRows または DataColumns の数が増えてもコストがかからないことを意味します。

DataStorage が値に配列を使用するのは興味深いことです。行を追加または削除すると、簡単に再構築できるとは想像できません。

于 2008-10-29T18:28:58.057 に答える
0

どんなタイプのハッシュテーブルも使用しないと思うので、ルックアップはO(n)になると思いますが、実際には行と列を見つけるためにより多くの配列を使用します。

于 2008-09-28T01:01:16.587 に答える
0

実際、列名はハッシュテーブルに格納されていると思います。大文字と小文字を区別するルックアップの場合は、O(1)または定数ルックアップである必要があります。それぞれを調べなければならない場合、もちろんそれはO(n)になります。

于 2008-09-28T01:09:32.107 に答える