- - PR -
【C#】単一テキストファイルから重複行削除
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2006-06-14 10:01
あっ! す、すみません。大きく勘違いしていました(汗 >がらす様 なるほど・・・ StringBuilderが早いというのは知っていたのですが、何がどう早いのか 理解していませんでした・・・。 >StringBuilderはあらかじめ大き目のメモリを確保しておいて とのことですが、例えばメモリが256MB程度しか積んでいないPCの場合は、 StringBuilderが先にメモリの確保をすると、一瞬PCが遅くなったりしないのでしょうか? StringBuilderに限った事ではないと思うのですが、どのタイミングでメモリの解放が 行われるのかな、と。 明示的にメモリ解放ってこの場合できたりするんでしょうか? | ||||||||
|
投稿日時: 2006-06-14 10:20
メモリの解放の話は過去スレもけっこうありますし、他の方に任せるとして…
他の方も仰っているように、今回のケースでは、StringBuilderすら使う必要はないと思います。 単純にStreamWriterのWriteLineでどんどん書いていけばいいと思いますよ? あと、直接時間を縮める処理ではありませんが、処理が「固まっていない」ことがわかり、かつ「今どれくらい進んでいるか」がわかれば、人間は以外と待てるものです。 なので、もし時間がかかるようなら、最初に select count(*) from (select distinct * from textfile.txt) AS A みたいなSQLで全体の件数を取得しておいて、365/10000 みたいなラベルを表示したり、プログレスバーを表示したりするのも一つの手だと思います。 ご参考 DOBON.NET .NET Tips - 時間のかかる処理の進行状況を表示する DOBON.NET .NET Tips - 時間のかかる処理をユーザーが停止できるようにする [ メッセージ編集済み 編集者: ぼのぼの 編集日時 2006-06-14 10:28 ] | ||||||||
|
投稿日時: 2006-06-14 10:37
StringBuilderを使用しないで直接書き込む処理に変更したら ものすごく早くなりました! 何か処理する→変数に入れる→それを書き込む、といった考えをする癖があり、 何の迷いもなくそうしていました…(恥)。 人間が待てるレベルの速さになったのですが、念のためプログレスバーなどの 処理も考えてみます。 まだまだ課題が沢山(これを応用して、単一ファイルではなく複数ファイルから読込、重複削除や、指定した文字列を同時に削除など)あるのですが、大きな壁がクリアできて 本当に嬉しいです! じゃんぬねっと様、がうしぇ様、なちゃ様ぼのぼの様、夏椰様、R・田中一郎様、がらす様 ありがとうございました!! | ||||||||
|
投稿日時: 2006-06-15 10:13
解決済みになってしまいましたが、ぼのぼのさんの提案「(1) Hashtable を使う方法」を使う方法が議論されていないのでサンプルを提供します。
私の環境では、ファイルサイズ 10MByte 12万行が3・4秒で終了します。
メモリ内に収まるサイズであればHashtableを使うと良いと思います。 メモリに収まらないような数ギガのファイルは、ファイルを分割してマージソート&重複する文字の削除を行うのが良いと思います。 | ||||||||
|
投稿日時: 2006-06-15 11:47
サンプルありがとうございます。 その後いろいろ処理を追加(読み込んだファイルからNGリストに載っている文字列を削除、複数ファイルからの重複削除)してみたところ、 テーブルで行う場合とハッシュで行う場合、ハッシュのほうが早い事が判明しました。 現状は、ソート機能も必要なので、ソートしない→HushTable、ソートする→SortedList で分けて処理をしようかな、と思っています。 ちなみになのですが、Hushtableから、Keyのみを全部取得する場合はどうすればよいのでしょうか? いろんなサイトを見てみましたが、KeyとValueが1組で取得したりようで…。 SortedListにあるGetKey()のような機能はHushTableにはないのでしょうか…。 | ||||||||
|
投稿日時: 2006-06-15 13:48
こんにちは。
Hushtableから、Keyのみを全部取得する場合は・・ 例えば以下のような感じで取得することが可能ですよ。 ------------------------------------------------------- Private htb As New Hashtable (いろいろ省略) Dim ide As System.Collections.IDictionaryEnumerator = htb.Keys.GetEnumerator While ide.MoveNext Console.Write(DirectCast(ide.Current, String)) End While ------------------------------------------------------- #VBで書いてしもた・・ #このスレは結構勉強になりました。 [ メッセージ編集済み 編集者: むら 編集日時 2006-06-15 13:50 ] | ||||||||
|
投稿日時: 2006-06-15 15:49
またも問題が・・・
ソートリスト使用時、10万件のデータで sr = new StreamReader(ifn[i].ToString(),Encoding.GetEncoding("Shift_JIS")) ; string rl ; while ((rl = sr.ReadLine()) != null) { if(!sortlist.ContainsKey(rl)) { sortlist[rl]="OK"; //sw.Write(sortlist.ToString() ); //sw.Write( "\r\n" ); } 上記の処理で50秒近くかかる事が判明しました… 本当はHushTableでソートできれば一番いいのですが、どうもできないようなので ソートリストを使ってみたのですが…。 仮想テーブルを使用したほうが早いのですが、NGリスト除去処理を行おうとして string sql = "SELECT DISTINCT * FROM textfile.txt EXCEPT SELECT DISTINCT * FROM ngfile.txt"; 上記のようなSQLを投げるとエラーが帰ってきてしまいます。 (UNION系は大丈夫でした。INTERSECT 、EXCEPTだとエラーになるようです) 一難去ってまた一難です… | ||||||||
|
投稿日時: 2006-06-15 16:08
SELECT DISTINCT * FROM textfile.txt where f1 not in (
SELECT f1 FROMngfile.txt) こんなSQLでいけるんじゃないでしょうか? _________________ 夏椰 @ わんくま同盟 夏椰の庵 Microsoft MVP for Windows Server System - SQL Server ( Jul 2006 - Jun 2008 ) |