Visual Studio 2017を使っています。
CSVファイルを読み込んでソートを行ってDataGridView(DGV)に表示するということをしたいのですが、
CSVファイルには約10万件のデータがあります。
処理時間を短縮したいですが何か良い方法はありますでしょうか?
実行した方法二つを載せておきます。
よろしくお願いいたします。
方法1 方法2の4倍の時間がかかりました。
1.csvファイルを読み込む
2.シリアルNo.の重複の確認を行う
3.DGVに表示
2.と3.を繰り返す
4.並べ替え
C#
1void InportcsvToDGV() 2 { 3 int iCount = 0; 4 5 string csvLine; 6 string[] csvData; 7 string[] DGVData; 8 DGVtable.ColumnCount = 10; 9 10 // read csv file 11 if (File.Exists(Inportcsvpath)) 12 { 13 DGVtable.Rows.Clear(); 14 15 StreamReader csvFile = new StreamReader(Inportcsvpath, Encoding.GetEncoding("UTF-8")); 16 do 17 { 18 bool overlap = false; 19 20 // read csv file 21 csvLine = csvFile.ReadLine(); 22 csvData = csvLine.Split(','); 23 24 DGVData = new string[10] 25 { 26 "name", 27 csvData[0], csvData[1], csvData[2], 28 csvData[3], csvData[4], csvData[7], 29 csvData[8], csvData[9], csvData[10] 30 }; 31 32 if (iCount != 0) 33 { 34 for (int i = 0; i < DGVtable.RowCount-1; i++) 35 { 36 if (DGVtable.Rows[i].Cells[4].Value.ToString() == DGVData[4]) 37 overlap = true; 38 } 39 } 40 // display 41 if (overlap == false) 42 DGVtable.Rows.Add(DGVData); 43 44 iCount++; 45 Txtcount.Refresh(); 46 47 } while (csvFile.Peek() != -1); 48 csvFile.Close(); 49 DGVtable.Sort(DGVtable.Columns[4], ListSortDirection.Ascending); 50 } 51 }
方法2
1.csvファイルを読み込む
2.DataTableを作成
3.DataTable作成中に重複削除
4.DGVに表示
5.並べ替え
C#
1void InportcsvToDT() 2 { 3 string csvLine; 4 string[] csvData; 5 6 DataSet Dset = new DataSet(); 7 DataTable table = new DataTable("Table"); 8 9 // read csv file 10 if (File.Exists(Inportcsvpath)) 11 { 12 table.Rows.Clear(); 13 StreamReader csvFile = new StreamReader(Inportcsvpath, Encoding.GetEncoding("UTF-8")); 14 do 15 { 16 // read csv file 17 csvLine = csvFile.ReadLine(); 18 csvData = csvLine.Split(','); 19 20 try 21 { 22 table.Rows.Add( 23 "name", 24 csvData[0], csvData[1], csvData[2], 25 csvData[3], csvData[4], csvData[7], 26 csvData[8], csvData[9], csvData[10] 27 ); 28 } 29 catch (ConstraintException) 30 { 31 errCounter++; 32 TxtLog.Text += csvData[4] + " is already produced.....\r\n"; 33 } 34 } while (csvFile.Peek() != -1); 35 csvFile.Close(); 36 } 37 DGVtable.DataSource = table; 38 DGVtable.Sort(DGVtable.Columns[4], ListSortDirection.Ascending); 39 40 TxtErrCounter.Text = errCounter.ToString(); 41 errCounter = 0; 42 }
質問は何ですか? 方法1は方法2の 4 倍の時間がかかるので問題外であれば、方法2を採用ということで良いのではないですか? 方法2より良い方法がないかというのが質問ですか?
ボトルネック(時間がかかる処理)はどこか切り分けることはできているのでしょうか? まだならそれをやってもらえませんか? 実環境でそれができるのは質問者さんしかいませんので。
提示されている2つの処理が等価ではありませんがいいのですか?
本題とは違う話で何ですが・・・
ファイルを一行ずつ読んで文字列を作り、String.Split メソッドでその文字列を区切るといった方法を取っているようですが、それで問題ないのですか?
改行コードやデリミタがフィールド値の中にあったり、改行コードが異なったりするのに対応する場合、そのような単純な方法は使えません。その場合どのように対応しするかは以下の記事を見てください。
CSV形式のファイルをDataTableや配列等として取得する
http://dobon.net/vb/dotnet/file/readcsvfile.html
例外で重複削除はいただけないです。
方法2よりも早く処理が終わるものがあれば教えていただきたいです。
ボトルネックは重複の確認です。
方法1で重複の確認を行わなければ1/10以下の時間で終わりました。
方法2でも同じ感じです。
方法2のほうで現在は進めていて更新部分が方法1に反映されていない部分があります。
申し訳ありません。
DataGridView の DataSource に全件放り込んでるみたいですが、
画面が固まったりしませんか?
DataGridViewに反映する部分はあまり処理に時間はかかっていいないと思います。
1秒もかからないうちに反映できています。
ありがとうございます。
WPF の DataGrid で同じようにやろうとすると確実に固まるので気になったのですが、
Windows.Formsはそのあたり高速ですね。
10000件のデータ (各10~20文字のstring型を10項目保有)で方法2でやったところ
総時間 約2.4秒
CSV読み込みと重複確認 約2.3秒
tableをDGVへ入れる 約0.6秒
ソート 約0.4秒
でした。
つまりこの質問にDataGridViewは無関係ということですか?
DataTableにループで行追加すると時間がかかるがなぜか?という質問が本質でしょうか?
そうですね。
最初は、何を使えば早くなるのかわからなく、もしかしたら使いこないしていない機能を使えばできるのかもしれないと思い、現状と使っているものを全て書きました。
回答4件
あなたの回答
tips
プレビュー