2011-12-28 7 views
1

나는이 목록의 깊은 복사본을 만들고 싶어가장 빠른 방법은

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

(즉, 각 DataTable에 복사)와 같은 DataTables의 목록을 가지고있다. 내 코드는 현재 모양이 같습니다

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

성능이 절대적으로 끔찍합니다. 그런 복사본을 빠르게 만들 수있는 방법이 있는지 궁금합니다.

편집 : 그냥 당신이 본질적으로 데이터 테이블을 복사 할 경우 내가

+0

DataTables의 목록이 어떻게 "큰"인가? –

+0

이러한 요구 사항을 계속 수행하면서 속도를 높일 수 있다고는 생각하지 않습니다. (즉, 깊은 사본입니다.) 또한 코드의 디버그 버전보다 RELEASE 버전의 코드에서 성능이 향상됩니다. – Dracorat

답변

2

을 변경할 수 없습니다 레거시 코드베이스의 일부임을 동의, 내가 이것을 왜 걱정이나이 작업을 수행 할 필요가 없습니다 N 시간 작업. 데이터 테이블이 매우 크고 많은 양의 할당이 발생하면 한 번에 섹션을 수행하여 작업 속도를 높일 수 있지만 본질적으로 작업 세트로 제한됩니다.

2

다음과 같이해볼 수 있습니다. 마일리지가 다를지라도 성능이 향상되었습니다! 예제를 사용하여 대체 메커니즘을 사용하여 데이터 테이블을 복사하는 방법을 보여줍니다. 테이블을 복제 한 다음 데이터를 스트리밍합니다.이 방법은 쉽게 확장 메서드에 넣을 수 있습니다. 우리가 DataTable.Copy가 ILSpy 사용하고있는 것을 보면, 또한

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

:

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 주위 내 사용의 경우) 다음과 같은 이상이었다

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(); 
    } 
관련 문제