1

バッチでデータテーブルを列挙したいと思います。IEnumerable<DataTable>そのために、次のようなメソッドを返すメソッドを作成しました。

public IEnumerable<DataTable> EnumerateRowsInBatches( DataTable table, int batchSize ) {

    int rowCount = table.Rows.Count;
    int batchIndex = 0;
    while( batchIndex * batchSize < rowCount ) {
        DataTable result = table.Clone();
        int batchStart = batchIndex * batchSize;
        int batchLimit = ( batchIndex + 1 ) * batchSize;
        if( rowCount < batchLimit )
            batchLimit = rowCount;
        for( int i = batchStart; i < batchLimit; i++ ) {
            result.ImportRow( table.Rows[ i ] );
        }
        batchIndex++;
        yield return result;
    }
}

これは実際にはかなりうまく機能します。テーブル値パラメーターを使用して SQL Server に送信するために、これらのバッチを繰り返し処理しています。がImportRow経過時間の大部分を占めていることがわかりました。速度を上げたいと思います。

私はそれを行う方法を探しています。すべてのデータを読み取り専用として自由に扱うことができるので、ここでは行のコピーが厳密に必要ではないことがわかります。

4

1 に答える 1

4

テストで最大 40% のパフォーマンス向上につながるアプローチを採用しました。

public static IEnumerable<DataTable> EnumerateRowsInBatches(DataTable table,
                                                            int batchSize)
{
    int rowCount = table.Rows.Count;
    int batchIndex = 0;
    DataTable result = table.Clone(); // This will not change, avoid recreate it
    while (batchIndex * batchSize < rowCount)
    {
        result.Rows.Clear(); // Reuse that DataTable, clear previous results
        int batchStart = batchIndex * batchSize;
        int batchLimit = (batchIndex + 1) * batchSize;
        if (rowCount < batchLimit)
            batchLimit = rowCount;

        for (int i = batchStart; i < batchLimit; i++)
            result.Rows.Add(table.Rows[i].ItemArray); // Avoid ImportRow

        batchIndex++;
        yield return result;
    }
}
于 2013-10-08T21:41:17.000 に答える