- - PR -
カンマ区切りの行の高速読み込みでプログレスバーを出す。(C++)
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2005-11-22 18:24
大きいサイズのファイルを開いてカンマ区切りの行を読み込んで解析したいのですが、ファイルのサイズが大きいため時間がかかってしまいます。
そこで、プログレスバーを出すことにしました。 ftell(fp) / (double)filesize * 100 で、プログレスバーの値をとることにしましたが、ftellは2Gまでしかサポートしていません。 他にファイルの現在位置を取得する方法はないでしょうか? また、この方法以上に高速に読む方法はありますか? 今は、 while(fscanf(fp,"%d %d\n",&t,&t1) != EOF) という方法で一行取得しながら読み込んでいます。 アドバイスよろしくお願いいたします。 | ||||||||
|
投稿日時: 2005-11-22 19:08
こんばんわ。
2GB超のファイルポインタの位置を取得するためには、 Windowsネイティブの関数である、 CreateFile、 ReadFile、 SetFilePointerEx などを使用しなければならないです。 上記を使用してファイルポインタの位置をとるには、 SetFilePointerEx(hFile、0,&newPos, FILE_CURRENT); でnewPosに取得できます。 ただこれらの関数群を使うと、文字列の一行単位での読み込みが 激しく面倒になります。 高速化についてですが、シーケンシャルなアクセスのようなので、CreateFileの引数にFILE_FLAG_SEQUENTIAL_SCAN を指定してやると高速に動作する可能性はあります。 #期待はそれほどもてませんが。 | ||||||||
|
投稿日時: 2005-11-22 21:40
実際速くなるかはやってみないとわからないから、どうだか判らん。
俺は優しくない(ある意味やさしい)ので、速くなるか確認しません。 1MBとか一気にメモリ上に読み取るとか。 fscanfで一寸ずつ読むより速いかもしれない。 原因がファイルをちまちま読み込むことだったらね。 そうでなかったら無駄骨になるってことかも。 ただ、1MBのところがちょうど改行の位置になるとは限らない。 その辺の処理が面倒で、どれくらい速くなるかも不明ときたもんだ。 while(fscanf(fp,"%d %d\n",&t,&t1) != EOF) を使わず自分で数字を読み込む処理を書くとか。 sscanfより速いコードを書けるなら速くなるでしょう。 速くならなかったらatoiやsscanfを使うとか。 | ||||||||
|
投稿日時: 2005-11-23 10:46
未記入さんが書いておられますが、自分も、
まとめてBYTEの配列に読み込んでそれをつなげながら、 文字列クラスで取り出してゆくのが良いかと思います。 キャッシュの効き具合で効果の度合いも違うかと思います。 更には、読み出し側を別スレッドにしてやると速くなります。 デッドロックしないプロダクト-コンシューマーパターンのテーブルを ひとつご自分の自作ライブラリに加えておかれると、 今後色々使い回しが出来て便利かと思います。 | ||||||||
|
投稿日時: 2005-11-23 22:41
すみません、教えてください。 これ、どういう意味でしょう?私は、作り方によっては、ユーザインタフェースのレスポンスがよくなるだけで、読み込み処理が速くなるとは思えないのですが。逆に、作り方によっては、ユーザにレンスポンスを返しながら、実行しなければならないスレッドが増えるので、遅くなると思うのです。 ___________________________________________________________________ □ written by Jitta on 2005/11/23 □ Microsoft MVP :Visual Developer ASP/ASP.NET Oct.2005-Sept.2006 _________________ | ||||||||
|
投稿日時: 2005-11-23 22:45
そうですね、通常「処理」は遅くなりますね。 「体感速度」に関する話だと思います。 _________________ C# と VB.NET の入門サイト じゃんぬねっと日誌 | ||||||||
|
投稿日時: 2005-11-24 07:29
いや、作り方によっては十分に早くなりますよ。HDDは低速なデバイスです。ファイルの読み込み完了を待つ間に、読み込んだデータの解析を同時に行えば、高速化できます。ファイルの読み込みを別スレッドで実行し、2行目を読み込んでいる間に、別のスレッドで1行目の解析を同時に行うわけです。WindowsAPIを使うなら非同期ファイルI/Oを使っても良いでしょう。 最近はHyperThredingやDualCoreプロセッサが採用されており、複数の論理CPUを持っていることが少なくありません。この点でも複数のスレッドに処理を分割するのは十分に有効でしょう。 | ||||||||
|
投稿日時: 2005-11-24 08:48
ああ、処理全体の話でしたか。 てっきり「読み込み」だけのお話かと思っていました。(;_ _) _________________ C# と VB.NET の入門サイト じゃんぬねっと日誌 |