VCでcsvファイル内検索

[戻る]
ひろ 2004/01/20(火) 17:05:50
VC++でデータが行数19万件、列数100件ほどの膨大なデータを
検索し、表示するツールを作ろうと思っています。
処理的にはすごく簡単でヒットしたものを表示させるだけです。
検索項目的には、キー項目的番号と名前などキーのはれない
データの検索もありです。

CSVファイルから直接検索するのも時間かかりますし、
一旦メモリに読み込んでというのも厳しく・・・
データベースにいれてしまえば?というのも無理な現状
(システムがダウンしたときのための緊急処理的システム)
のため、なるべく必要なランタイムなども省きたいのも現状です。
いろいろアルゴリズムを考えてはいるのですが、
なかなか無謀でしょうか・・・

なにかよい方法があればと思い教えて頂ければと投稿してみました。
よろしくお願いいたします。

クール 2004/01/20(火) 17:22:24
すいません、すぐ下に同じ名前がいたので変更しておきます;

あと環境を書くのを忘れておりました。
開発環境 VC++6.0,WINXP MFCあり
実行環境 指定なし(NT,98,2000が主ですが)

2004/01/20(火) 17:55:07
先ず、あなたの案を示してください(そうでないと、それはもう考えましたということに
なり兼ねませんから、無駄を省くためにも大切なことでしょう?)
幾つか質問があります

>一旦メモリに読み込んでというのも厳しく・・・
何故厳しいと判断できるのですか(根拠、判断基準が知りたい)

>名前などキーのはれないデータの検索もありです。
何故、キーがはれないとお考えになるのですか(根拠、判断基準が知りたい)

>CSVファイルから直接検索するのも時間かかりますし、
検索時間はどうやって計りましたか(測定の条件はどのように決めましたか)
どの程度の時間なら合格ですか

データーの更新の程度(頻度や量)はどうなんでしょうかまた、削除と追加と更新とは
どういう頻度で発生する傾向なんでしょうか(CSVなのでほとんど追加しかないのですか)

ななし 2004/01/20(火) 18:29:31
単純に

  FILE *fp;
  int cnt =0;
  char buf[1000];

  fp = fopen("d:\\test.text.txt","r");

  for(;;) {
    if(feof(fp)!=0) break;
    fgets(buf,999,fp);   
//    if(memcmp(buf , "AA",2) ==0) cnt ++;

  }


等としたときにファイルの終りまで読み込むのに何分(秒)くらいかかるのでしょうか?

うちの環境で試してみたところ大体6秒くらいでした。
(ファイルサイズ 約190MByte 19万行*973列)
また、memcpy入れた程度では時間にほとんど差はありませんでした。(目測ですが。。)
#フィールドが可変長のCSVで、カンマで分けたりをループの中に入れると
#もう少し時間かかるかもしれないですね。

>検索時間はどうやって計りましたか(測定の条件はどのように決めましたか)
>どの程度の時間なら合格ですか
#すいません、島さんの言わんとしている事と同じです。

クール 2004/01/21(水) 09:14:10
もうしわけありません、確かにそのとおりです。

現在、
    CCsvFile file;
    CString str;
    cFileName = "C:\\Test.csv";

         if( file.Open(cFileName,CFile::modeReadWrite) == FALSE ){
        return;
    }

    while(file.ReadCSV()==TRUE ){
        file.GetDataStr(str,1);
         if (str== "ウ0000010000"){
        AfxMessageBox("ヒット!");
        file.Close();
        return;
      }
     }

クール 2004/01/21(水) 10:21:51
すいません、誤って送信してしまいました。

現在簡単にどれくらいかかるのかをVBとVCで同じような処理で比較したところ
VCのほうが早かったためVCを考えています。
VCで作成したものは下記のソースです。
今後ヒットしたものはその行のデータ表示させることを考え(レコードイメージ)
こちらにあるCCsvFileクラスを使わせて頂いています。

CCsvFile file;
CString str;
CString cFileName;

//ファイルオープン
cFileName = "C:\\Test.csv";
if( file.Open(cFileName,CFile::modeReadWrite) == FALSE ){
   return;
}

//ファイル読込
while(file.ReadCSV()==TRUE ){
   file.GetDataStr(str,1);

   if (str== "ウ0001000000"){
    AfxMessageBox("ヒット!");
    file.Close();
    return;
   }
}
AfxMessageBox("全検索終了");
file.Close();

こちらのスペック(PentiumV,memory256)で1分ほど、VBだと1分半だったと思います。


>何故厳しいと判断できるのですか(根拠、判断基準が知りたい)
実行環境に厳しいものが多く(Memory64MBなど)一旦メモリにすべてのデータ
をもつと余計遅くなる、固まりかねないと考えた次第です。
実際試したわけではないので根拠といえませんが…

>何故、キーがはれないとお考えになるのですか(根拠、判断基準が知りたい)
少し説明が不適切、不十分でした、すいません。
キーがはれないというのは名前には同姓同名がある場合も考えられるということです。
あとあいまい検索をすることもあるので検索結果は複数件が大いに考えられます。


>データーの更新の程度(頻度や量)はどうなんでしょうかまた、削除と追加と更新とは
>どういう頻度で発生する傾向なんでしょうか(CSVなのでほとんど追加しかないので
>すか
これに関してはないと考えて頂いてかまいません。
このプログラム自体は検索のみで、データが更新されるというのはCSVファイル自体が
かわることになります。
本サーバがダウンしたときの緊急処理的なものなので使っているときにデータが変わる
ことはないからです。(サーバがダウンしていたらデータが吸い取れないため)

どの程度なら合格というのは特になかったのですが、上記のソースで最後の19万行目
をヒットさせようとするとかなりの時間がかかりそうだと思ったため、他に方法は
ないかと相談したしだいです。

説明が不十分だったことをお詫びいたします。

2004/01/21(水) 11:29:09
以下に述べるのはデーターを予め読み出しでメモリーに置いておかない場合です

>どの程度なら合格というのは特になかったのですが、上記のソースで最後の19万行目
>をヒットさせようとするとかなりの時間がかかりそうだと思った
べた読み(頭から尻までデーターをなめる)で一分なら平均は30秒でこれで合格の場合
何も工夫は要らないと思います

検索をこれより格段に早くしたいのならそれなりの工夫がいるでしょうが、要は実データー
のアクセスが早くならないので(CSV形式だから)早く読める(検索できる)データー
形式に一旦変換することになるでしょう。
この場合、下ごしらえにそれなりの時間が掛かりますが(数分から数十分程度)それでも、
検索が早い方がいいのかどうかでもやり方が変わってきませんか?

後、複合条件での検索があるか、さらに複数件一致するものがある場合どうしたいのか、
作業用の一時ファイル(があった場合)の後始末はどうするのか等つめなければならない
ことが残っていませんか?

渋木宏明(ひどり) [HomePage] 2004/01/21(水) 11:29:47
>このプログラム自体は検索のみで、データが更新されるというのは
>CSVファイル自体がかわることになります。

CSV が変わった時に CSV から .mdb を作成して、そこから検索すれば?

検索だけなら、(プログラムがタコでない限り)いくら .mdb でもそうやすやすとは壊
れないですよ。

あるいは、自力でDBの真似事をして、CSV からインデックスに当たる情報を作り出し
てそれを利用するようにするか。

クール 2004/01/21(水) 13:37:07
島さん、渋木さん返答有難うございます。

>検索をこれより格段に早くしたいのならそれなりの工夫がいるでしょうが、要は実デー
ター
>のアクセスが早くならないので(CSV形式だから)早く読める(検索できる)データ>形式に一旦変換することになるでしょう。
かなり重要なデータなため、手を加えすぎるのは危険なので、
検索をスムーズにするための変換というのならばよいかもしれません。

>CSV が変わった時に CSV から .mdb を作成して、そこから検索すれば?
これは考えました。なんだかんだいって速いです。
ただ初めに書いていますが余計なランタイムその他インストールを必要とするものは
省かないとといけない、ということはわかっているので、なるべく
VCオンリーで一番早くひっぱれるアルゴリズムはあるのかということを
まず調べてみたかったのです。
まだ調査段階で詳しい仕様も決まってない状態で聞いたのも悪かったのですが;

島さんの言っているように、データを変換するか、
あるいは渋木さんのいうIndexファイルを作るか
この二つも加えさらに調べてみようと思います。

渋木宏明(ひどり) [HomePage] 2004/01/21(水) 14:25:19
>島さんの言っているように、データを変換するか、
>あるいは渋木さんのいうIndexファイルを作るか
>この二つも加えさらに調べてみようと思います。

どっちもほとんど同じことを言っています。

「インデックスを作る」のは、データ変換の一形態でしかありません。

汎用性を得ようと思うと、現代のデータベースエンジンの多くが採用しているのと同じ
方向に行かざるを得ないと思います。

CSV は、データ交換用に広く用いられているデータ形式ですが、間違っても効率よい検
索を行うためのデータ形式ではありません。

CSV のみしか材料が無い状態で高速な検索を行うのは、登録件数が多ければ多いほど絶
望的な挑戦と思います。

古いスレッドには追加発言できません。