- - PR -
【C#】単一テキストファイルから重複行削除
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2006-06-13 18:26
おらのパソコンにはSFUがはいっているので 同一ファイルで実験やってみましたよ。
でした。 やっぱりコマンドいいっすね♪ _________________ 夏椰 @ わんくま同盟 夏椰の庵 Microsoft MVP for Windows Server System - SQL Server ( Jul 2006 - Jun 2008 ) | ||||||||
|
投稿日時: 2006-06-13 18:35
R・田中一郎様
・少ない件数で試してみる。 →3000件程度だと40秒?程度で処理を終了します。 ・どの部分で帰ってこないのか確認する。(DBエンジン側の処理で帰ってこない?) → 帰ってこない、という言い方はおかしいですが、 while (dr.Read() == true) { strData += dr.GetValue(0); strData += "\r\n"; } 上記のLoopで延々と処理してるので、レスポンス的に5分以上メモリも保持してる 感じです。 ・書き込み処理はどうしてます? →LoopでString変数に代入したものをStreamWriterで吐き出しています。 夏椰様
30秒・・・う、うらやましいです。 プログラムはVS2003のC#にて作成、実行しています。 下記がソースです。 (実際は、StreamWriterの書出処理は別ロジックにあり、それを呼び出しています) private void Sample() { int itime; string strData = null; OleDbConnection con = new OleDbConnection(); OleDbCommand oCommand = new OleDbCommand(); try{ string sql = "select distinct * from textfile.txt"; con.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\;Extended Properties=\"text;HDR=NO;FMT=Delimited\""; oCommand.Connection = con; oCommand.CommandText = sql; OleDbCommand cmd = new OleDbCommand(sql, con); con.Open(); OleDbDataReader dr = cmd.ExecuteReader(); while (dr.Read() == true) { strData += dr.GetValue(0); strData += "\r\n"; } con.Close(); StreamWriter sw = new StreamWriter(@"c:\filedata.txt", false,System.Text.Encoding.GetEncoding(932)); sw.Write(strData); sw.Close(); } catch (Exception oExcept) { MessageBox.Show(oExcept.Message, "エラー"); } } | ||||||||
|
投稿日時: 2006-06-13 18:43
これネックになりますよね?(^^; 自分のロジックでわざと 上記処理を記述すると遅くなりますもん。 見ていると、ファイル読込→溜め込み→書き出しになっていますが、 せっかくSQL文でDISTINCTつけて重複省いているので、 読み取ったデータは即書き込んでもいいと思ったんですが、駄目ですかね? そうすれば、変数に足しこんでいかなくても済みますよね。 ----------------- 以下追記 自PCでの実験で 溜め込むとしてもStringBuilderを使えば問題なかったですよ。 _________________ 夏椰 @ わんくま同盟 夏椰の庵 [ メッセージ編集済み 編集者: 夏椰 編集日時 2006-06-13 18:45 ] | ||||||||
|
投稿日時: 2006-06-13 19:00
strData += "rn"; ←これがネックでしたか・・・。 StringBuilderを使用して試してみました。なるほど、高速です。 この状態だと、全てが一行?の状態になってるのですが、 出力ファイルの中身を行単位で改行してあるデータにしたい場合は どのタイミングで改行を行うべきでしょうか? | ||||||||
|
投稿日時: 2006-06-13 19:02
文字列の連結は毎度新しい領域に全てコピーしなおすので、大量のものだと重くなるんですよ^^;
夏椰さんのいうように、StringBuilderを使うと高速に連結できます。 | ||||||||
|
投稿日時: 2006-06-13 23:53
それもそうですし、今回の場合は例えば一行ずつ処理しながら ファイルに書き出すなどしていけばいいでしょうから、 そもそも文字列をすべて連結する必要自体ありません。 やらなくていいことはやらずに済ますのが基本です(特に負荷がかかるような処理は)。 | ||||||||
|
投稿日時: 2006-06-14 09:13
なんか勘違いされている気がしました・・・・。 Stringの変数を+=で連結していくことが問題であり、 改行コードを連結することが問題ではありません。 #よって # strData += "rn";だけでなく # strData += dr.GetValue(0); も問題なんですよ。 理由については R・田中一郎さんがフォローしてくれています。 また、なちゃさんもおっしゃっていますが、 変数にためる必要性を今一度、ご考慮くださいませ。 _________________ 夏椰 @ わんくま同盟 夏椰の庵 Microsoft MVP for Windows Server System - SQL Server ( Jul 2006 - Jun 2008 ) | ||||||||
|
投稿日時: 2006-06-14 09:56
こんなのもあります。
http://sonic64.com/2005-11-30.html += で連結していく場合、string をそのまま連結すると、StringBuilderを使った時の100倍ぐらい時間がかかるという話です。 StringBuilderはあらかじめ大き目のメモリを確保しておいて、そこに文字列を継ぎ足していくのですが、stringは += が1回実行されるたびに新たにメモリを確保してコピーをするからです。メモリ確保もコピーも時間がかかるのです。 |