パフォーマンスが向上するかどうかを確認するために並行して実行することにした負荷の高い操作中にリストの順序を維持することについて、いくつかの入力が必要です。(やった!)
私は解決策を思いつきましたが、これが私の最初の試みだったので、私が非常に愚かなことをした場合、誰かに手を叩いてもらう必要がありました.
カード所有者のリストを、名前順、生年月日順で返すクエリがあります。これは、Web ページ (ASP.Net WebForms) のテーブルにレンダリングする必要があります。元のコーダーは、セルごとにテーブルを作成し ( TableCell
)、それらを行に追加し ( TableRow
)、各行をテーブルに追加することを決定しました。したがって、GridViewはありません。パフォーマンスが悪いと言われていますが、パフォーマンスは非常に悪かったです:)。
データベース クエリはすぐに返されます。ほとんどの時間は、結果のループ処理やテーブル セルの追加などに費やされます。
リストの元の順序を維持するために、次のメソッドを作成しました。
private TableRow[] ComposeRows(List<CardHolder> queryResult)
{
int queryElementsCount = queryResult.Count();
// array with the query's size
var rowArray = new TableRow[queryElementsCount];
Parallel.For(0, queryElementsCount, i =>
{
var row = new TableRow();
var cell = new TableCell();
// various operations, including simple ones such as:
cell.Text = queryResult[i].Name;
row.Cells.Add(cell);
// here I'm adding the current item to it's original index
// to maintain order in the output list
rowArray[i] = row;
});
return rowArray;
}
ご覧のとおり、非常に異なるタイプのデータ ( List<CardHolder> -> TableRow[]
) を返しているため、元のクエリから順序付けを単純に省略して操作の後に行うことはできません。
Dispose()
また、クエリが巨大なリストを返す可能性があり、セルと行のオブジェクトがヒープに積み上げられるとパフォーマンスに影響を与える可能性があるため、各ループの最後にオブジェクトを配置することも良い考えだと思いました.(?)
私はどれほどひどいことをしましたか?私のものに欠陥がある場合に備えて、誰かがより良い解決策を持っていますか?
テスト後、|2000| で 配列でStopWatch
は、並列合成は 63 ミリ秒 (165082 ティック) で完了し、直列合成は 267 ミリ秒 (698222 秒) で完了します。table.Rows.AddRange()
どちらも - ( ) に行を追加してからTable
. 追加とレンダリングを行わない場合、時間はパラレルで 33ms/87541t、シリアルで 178ms/467068t です。