- PR -

[C#] インデックス検索

1
投稿者投稿内容
影月
会議室デビュー日: 2005/06/02
投稿数: 2
投稿日時: 2005-06-02 01:57
こんばんは影月です。お世話になります。
現在、C#でインデックス検索をするツールを作っているのですが、
今の方法ではとても遅くて、ハングする事もあります。

今の方法は、コンストラクタでデータファイルを読み込み、内容を予め、
ArrayListに1行単位でAddしています。
次に、TextBoxのKey_DownイベントでEnterキーが押されるとforeachループとIndexOfによる条件のマッチをし、
条件に合うものを別のArrayListにAddしています。
さらに再びそれをforeachループにかけファイル名やらアイコンなどの取得をしています。
ちなみに表示先はListViewです。

明らかに効率の悪い方法なのですが、これ以外思いつきませんでした。
検索サイトや掲示板なども出来る限りあたったのですが有力な情報はありませんでした。
フリーのインデックス検索ツール『fenrir』の様な感じのものです。

文章が非常に読み辛いのに加え、根本的にインデックス検索の意味が違っているかも知れませんが、
どなたかご指導頂けないでしょうか?
一郎
ぬし
会議室デビュー日: 2002/10/11
投稿数: 1081
投稿日時: 2005-06-02 10:17
引用:

影月さんの書き込み (2005-06-02 01:57) より:
foreachループとIndexOfによる条件のマッチをし



foreachは分かるんですけど、IndexOf()は何に使っているんですか?
別のArrayListに追加するだけならIndexOf()は必要ないですよね。
117
ベテラン
会議室デビュー日: 2005/05/09
投稿数: 94
お住まい・勤務地: 大阪府
投稿日時: 2005-06-02 14:29
どの部分の処理で時間がかかっているかによって話が変わってくるのではないかと。

#既に掲示板等で調べられたそうですが、どの部分に当たりをつけて調べたか等を
#書いていただくと問題が見つけやすいかも


とりあえずパフォーマンス関連のドキュメントhttp://www.microsoft.com/japan/msdn/net/general/dotnetperftips.asp

_________________
# Future Is On Fire !
TLC
大ベテラン
会議室デビュー日: 2005/05/31
投稿数: 152
お住まい・勤務地: 東京都
投稿日時: 2005-06-02 15:07
インデックス検索というより,
テキスト全文検索,ワード検索のようなものを行っているということでしょうか?

全文検索でしたら,
見つかる頻度がどの程度か予想できるかできないかにもよりますが,

正規表現で該当文字を見つけてから位置情報を特定する
ような流れにしたほうが効率がよいのではないでしょうか?

検索にヒットしないであろう行を大量に Add することは,相当なオーバーヘッドになると思います。
burton999
ぬし
会議室デビュー日: 2003/10/06
投稿数: 898
お住まい・勤務地: 東京
投稿日時: 2005-06-02 15:13
やりたいのは、grepですよね?
grepなどはソースコードが公開されているでしょうから、参考にしてみてはいかがでしょう。
私は見たことないですが、おそらくかなり高度だとは思います。。。
なちゃ
ぬし
会議室デビュー日: 2003/06/11
投稿数: 872
投稿日時: 2005-06-02 16:46
引用:

影月さんの書き込み (2005-06-02 01:57) より:

現在、C#でインデックス検索をするツールを作っているのですが、
今の方法ではとても遅くて、ハングする事もあります。
--
文章が非常に読み辛いのに加え、根本的にインデックス検索の意味が違っているかも知れませんが、
どなたかご指導頂けないでしょうか?


とりあえず、なぜインデックス検索なんでしょう?

「インデックス検索」というものを実装しないといけないのだが、
そもそも「インデックス検索」の意味を理解できていないかもしれない、
というような状態なんでしょうか?
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2005-06-02 19:26
 fenrirって、これ

こんな感じか。
コード:
textBox1_KeyDown() {
	string str;
	foreach (str in arrayList1) {
		if (str.IndexOf(textBox1.Text) > 0) {
			arrayList2.Add(str);
		}
	}
	// アイコンなどを探す処理
}


 ArrayListはObjectの集合なので、System.Collections.Specialized.StringCollection クラスを使う方が、キャストかToStringメソッドの実行がなくなるぶん、速いでしょうね。

_________________
影月
会議室デビュー日: 2005/06/02
投稿数: 2
投稿日時: 2005-06-02 21:58
皆さん、様々な情報とご指導ありがとうございます。

ぬしさん
IndexOf()は条件にマッチするものを選び出す簡単なフィルタもどきのつもりなのです。
ただこれでは効率が悪いので、マルチスレッドでのIndexOf()とLastIndexOf()の
挟み撃ち検索やハッシュと正規表現の組み合わせなんかも考えました。
どれも、ソースが見難くなるだけであんまり効果は期待出来ないようなので単にIndexOfで
前から順番に調べています。

117さん
時間が掛かっているのは恐らく...
1.イベントがKey_Downである事
2.キーが押される度に検索後のArrayListが再構築される。
3.データが多いにも関わらずAddRangeでなく、Addを使っている
4.ToString()によるロス
5.プリコンパイルしていない?
等が関係していると思います。
1に関してはswitch文でe.KeyCodeでKeys.Enterの時に処理すれば何とかなると思います。
ただ、IME等の漢字の変換等による決定時にも適用されてしまう可能性があるのが少し
不に落ちないですが...。
教えて頂いたパフォーマンス関連の参考資料を参考に色々と考えてみます。

TLCさん
テキスト全文検索...そうですね。そんな感じです。
普通の検索ではデータ量?の関係もあって付加が掛かりそうなので、正規表現の使用は私も考えています。
位置情報に関しては方法がわかりませんバイト単位を行単位にして...
ArrayListならインデックスが返されるからそれを使えば何とか出来るかもしれないですね。

burton999
やっぱりGrepでしょうか?Perlでは命令一つで使えたのですが...
ソースの方、見ましたが、解読は出来ない事は無いですが、相当時間が掛かりそうです。
CをC#に移植もしくはC#の正規表現を織り交ぜて...
有る程度のアプリなら、まだしも小規模なツールなのでちょっとこれは避けたいですね。

なちゃさん
インデックス検索は私の解釈では予め論理ドライブ等に存在するファイルを検索して
パスをまとめたものをファイル化しておき、そのファイル内検索する事だと思っているの
ですが...違うのでしょうか?

Jittaさん
ソースはJittaさんの書かれた様な感じです。
そうですね。確かに大量のボックス化やアンボックス化はロスになり得るので
ArrayListクラスでなく、String.Collectionクラスを使えば高速化出来ますね。

皆さんの意見を参考にもう一度検索してみたのですが以下の様なものが見つかりました。
http://www.atmarkit.co.jp/fdotnet/basics/regex01/regex01_02.html
まさにこれです。
あと、問題はサイズなどの情報を取得するとまた時間が掛かってしまうと言う事ですが...
それは、今後の自分の課題とし、自力でなんとかしてみようと思います。
皆さんありがとうございました。
1

スキルアップ/キャリアアップ(JOB@IT)