2011-12-28 15 views
1

私はこのリストのディープコピーを作成したい最速の方法は、

List<DataTable> a = new List<DataTable>(); 

(すなわち、それぞれのDataTableのコピー)のようなのDataTableのリストを持っています。私のコードは、現在

List<DataTable> aCopy = new List<DataTable>(); 
for(int i = 0; i < a.Rows.Count; i++) { 
    aCopy.Add(a[i].Copy()); 
} 

のように見えるのパフォーマンスは絶対にひどいです、そして、そのようなコピーをスピードアップするために知られている方法がある場合、私は疑問に思って?

編集:ちょうどそれはあなたがデータテーブルをコピーする必要があれば、それは本質的に、私は

+0

のDataTableのリストがどのように「大きな」とは? –

+0

私はあなたがまだこれらの要件に取り組んでいる間にそれをスピードアップできるとは思わない。 (つまり、それは深いコピーです。)また、コードのリリースバージョンよりも、コードのDEBUGバージョンよりもパフォーマンスが向上することに注意してください。 – Dracorat

答えて

2

を変更することはできませんレガシーコードベースの一部であることを受け入れて、私はこれを持っているか、これを実行する必要がある理由については心配しないでくださいN回の操作。データテーブルが非常に大きく、大量の割り当てが発生する場合は、一度にセクションを実行することで操作をスピードアップすることができますが、基本的にはワークセットによって制限されています。

2

あなたは次のことを試すことができます - あなたの走行距離は変わるかもしれませんが、それは私にパフォーマンスの向上をもたらしました!私はこれをあなたの例に適用して、代替メカニズムを使用してデータテーブルをコピーする方法をデモンストレーションしました。テーブルをクローンしてからデータをストリームします。これを簡単に拡張メソッドに入れることができます。

List<DataTable> aCopy = new List<DataTable>(); 
for(int i = 0; i < a.Rows.Count; i++) { 
    DataTable sourceTable = a[i]; 
    DataTable copyTable = sourceTable.Clone(); //Clones structure 
    copyTable.Load(sourceTable.CreateDataReader()); 
} 

これは速い(私のユースケースでは6程度)以下のより多くの時間だった:

DataTable copyTable = sourceTable.Clone(); 
foreach(DataRow dr in sourceTable.Rows) 
{ 
    copyTable.ImportRow(dr); 
} 

また、我々はDataTable.CopyはILSpyを使用してやっていることを見れば:

public DataTable Copy() 
{ 
    IntPtr intPtr; 
    Bid.ScopeEnter(out intPtr, "<ds.DataTable.Copy|API> %d#\n", this.ObjectID); 
    DataTable result; 
    try 
    { 
     DataTable dataTable = this.Clone(); 
     foreach (DataRow row in this.Rows) 
     { 
      this.CopyRow(dataTable, row); 
     } 
     result = dataTable; 
    } 
    finally 
    { 
     Bid.ScopeLeave(ref intPtr); 
    } 
    return result; 
} 

internal void CopyRow(DataTable table, DataRow row) 
{ 
    int num = -1; 
    int newRecord = -1; 
    if (row == null) 
    { 
     return; 
    } 
    if (row.oldRecord != -1) 
    { 
     num = table.recordManager.ImportRecord(row.Table, row.oldRecord); 
    } 
    if (row.newRecord != -1) 
    { 
     if (row.newRecord != row.oldRecord) 
     { 
      newRecord = table.recordManager.ImportRecord(row.Table, row.newRecord); 
     } 
     else 
     { 
      newRecord = num; 
     } 
    } 
    DataRow dataRow = table.AddRecords(num, newRecord); 
    if (row.HasErrors) 
    { 
     dataRow.RowError = row.RowError; 
     DataColumn[] columnsInError = row.GetColumnsInError(); 
     for (int i = 0; i < columnsInError.Length; i++) 
     { 
      DataColumn column = dataRow.Table.Columns[columnsInError[i].ColumnName]; 
      dataRow.SetColumnError(column, row.GetColumnError(columnsInError[i])); 
     } 
    } 
} 

操作に時間がかかることは驚くことではありません。行単位であるだけでなく、追加の検証も行います。

0

リストの容量を指定する必要があります。そうでない場合は、データを格納するために内部的に拡張する必要があります。詳細な説明は、hereを参照してください。

List<DataTable> aCopy = new List<DataTable>(a.Count); 
0

私は、LINQのようなフィルタリングレコードの他の方法よりもはるかに効率的に次のようなアプローチを発見したシンプルで、検索条件を提供:

public static DataTable FilterByEntityID(this DataTable table, int EntityID) 
    { 
     table.DefaultView.RowFilter = "EntityId = " + EntityID.ToString(); 
     return table.DefaultView.ToTable(); 
    } 
関連する問題