大容量ファイル(100M以上ぐらい)の内容の比較を高速に行うには? – プログラミング – Home

大容量ファイル(100M以上ぐらい)の...
 
通知
すべてクリア

[解決済] 大容量ファイル(100M以上ぐらい)の内容の比較を高速に行うには?

固定ページ 1 / 2

Tome
 Tome
(@Tome)
ゲスト
結合: 18年前
投稿: 36
Topic starter  

毎度お世話になっております。

まず環境
VisualC++2005
Win32 PlatformSDK
WindowsXP/2000

現在ファイルをコピーする関数を作成しているのですが、単純なCopyFileを使ったものではなく、以
下のような特徴を持っています。

コピーの前にコピー元と先でファイルサイズと内容を比較し、一致すればコピーせずに終了、一致し
なければ、実際にコピーするかメッセージボックス等でユーザに問い合わせる。
「はい」を選択した場合コピーを開始し、プログレスバーなどで進捗を表示。

という感じです。

しかし大容量のファイルをコピーする際に、ファイルの比較に時間がかかりフリーズに近い状態に
陥ってしまいます。実際のコピー処理辞退はプログラスバーを使っているので大丈夫なのです
が、ファイルの比較になるべくプログレスバーは使いたくありません。(めんどくさいことも含め)

高速化を含めなにかいい方法はないでしょうか?

ちなみに現在は、比較に以下のようなReadFile等でちょびちょび読み込みながら比較を行っていま
す。最初はファイルのデータを全部一気に読み込んで比較していたのですが、メモリ不足で遅かった
ので、ちょびちょびに変えました。

if( size1[0] == size2[0] ){ >// サイズが一致したなら内容比較
>// 1024 : ちょびちょび読みつつ比較
int CmpSize = 1024;
if( size1[0] > (1024 * 1024 * 10) ) { >// 10M以上(たぶん
>// ファイルサイズが大きい場合はもう少し多めに
CmpSize = 1024 * 1024;
}

p1 = (BYTE*)malloc( CmpSize );
p2 = (BYTE*)malloc( CmpSize );
if( p2 )
{
while(1)
{
DWORD _size1, _size2;
>// ちょびっと読み込む
int success = ReadFile( hFile1, p1, CmpSize, &_size1, NULL );
if( success ) {
success = ReadFile( hFile2, p2, CmpSize, &_size2, NULL
);
}
if( !success ) { >// 読み込みエラー (基本的にない)
cmp_ret = -4;
break;
}
if( _size1 == 0 ) { >// 終端
cmp_ret = 0; >// 一致を戻り値にセット
break;
}

if( (_size1 != _size2) || memcmp( p1, p2, _size1 ) != 0 ) { >//
内容が一致しなければ
cmp_ret = 1; >// 不一致を戻り値にセット
break;
}
}
}
}

よろしくおねがいします。


引用未解決
トピックタグ
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 1301
 

で、今のやり方に不満があるのでしょうか?


返信引用
Tome
 Tome
(@Tome)
ゲスト
結合: 18年前
投稿: 36
Topic starter  

>で、今のやり方に不満があるのでしょうか?
比較で時間がかかり、フリーズした感じになるのを何とかしたい。
なんとかならないなら、せめて比較の時間だけでも短縮させたい。
という感じです。

↑の比較プログラムは何も考えず適当に作ったのでたぶん遅い。

現在150M程度のファイル同士(同じサイズ)でテストしているのですが、
コピー処理(SHFileOperation)は15秒程度で終わるのに対し、
上の比較では、60秒以上かかります。


返信引用
Tome
 Tome
(@Tome)
ゲスト
結合: 18年前
投稿: 36
Topic starter  

>で、今のやり方に不満があるのでしょうか?
比較で時間がかかり、フリーズした感じになるのを何とかしたい。
なんとかならないなら、せめて比較の時間だけでも短縮させたい。
という感じです。

↑の比較プログラムは何も考えず適当に作ったのでたぶん遅い。

現在150M程度のファイル同士(同じサイズ)でテストしているのですが、
コピー処理(SHFileOperation)は15秒程度で終わるのに対し、
上の比較では、60秒以上かかります。


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 1301
 

1- CmpSizeをもっと大きくすれば?
2- ループの合間にメッセージ・ポンプを押し込めば?
3- スレッドを分離すれば?

※ 2,3 は速くするんじゃなく、フリーズ除けですが。


返信引用
Tome
 Tome
(@Tome)
ゲスト
結合: 18年前
投稿: 36
Topic starter  

επιστημηさんありがとうございます。

> 2- ループの合間にメッセージ・ポンプを押し込めば?
> 3- スレッドを分離すれば?

なるほど。
この間にプログレスバーみたいなので進捗を表示すればいいわけですね。
まあ、プログレスバーはコピーの前処理(比較)にプログレスバー使うのも大げさなんで、砂時計
カーソルとかにするのがいいんですかね・・・・

> 1- CmpSizeをもっと大きくすれば?
10Mにしてみましたが、多少速くなる程度でしたね。
っていうか実際のコピー処理より前処理の比較の方が時間がかかるのが許せないですね。やっぱり
ループになにかしらの不具合があるのかな?


返信引用
Tome
 Tome
(@Tome)
ゲスト
結合: 18年前
投稿: 36
Topic starter  

> 比較で時間がかかり、フリーズした感じになるのを何とかしたい。
「フリーズ」って言葉はちょっと違かったかも・・・
比較処理の「間」のことです。

フリーズしなくても、変な「間」があると、やっぱり使ってる人は ん? って思いますし。


返信引用
Tome
 Tome
(@Tome)
ゲスト
結合: 18年前
投稿: 36
Topic starter  

> 比較で時間がかかり、フリーズした感じになるのを何とかしたい。
「フリーズ」って言葉はちょっと違かったかも・・・
比較処理の「間」のことです。

フリーズしなくても、変な「間」があると、やっぱり使ってる人は ん? って思いますし。


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 1301
 

> まあ、プログレスバーはコピーの前処理(比較)にプログレスバー使うのも大げさなんで、砂
時計カーソルとかにするのがいいんですかね・・・・

それはアナタが(動きを見ながら)決めること。


返信引用
Tome
 Tome
(@Tome)
ゲスト
結合: 18年前
投稿: 36
Topic starter  

ちょっと計測してみたのですが、
ReadFileが重いみたいです。

2回のReadFileと、memcmpの処理時間をQueryPerformanceCounterで計測してみました。
CmpSize : 1M (1024 * 1024)
回数:5
-------------------------
ReadFile : 1924323
Comp : 13604
ReadFile : 4301359
Comp : 13067
ReadFile : 22136
Comp : 13648
ReadFile : 21126
Comp : 13242
ReadFile : 1918485
Comp : 13509
--------------------------

なんかたまに早い時もありますね。

コピー処理はなんであんなに早いんですかね?(SHFileOperation内部ではReadFileを使ってない
のかな?)

ReadFileについて調べることにします。
ありがとうございました。

※もう少し情報ほしいので、まだ解決にチェックは付けません。


返信引用
Tome
 Tome
(@Tome)
ゲスト
結合: 18年前
投稿: 36
Topic starter  

ちょっと計測してみたのですが、
ReadFileが重いみたいです。

2回のReadFileと、memcmpの処理時間をQueryPerformanceCounterで計測してみました。
CmpSize : 1M (1024 * 1024)
回数:5
-------------------------
ReadFile : 1924323
Comp : 13604
ReadFile : 4301359
Comp : 13067
ReadFile : 22136
Comp : 13648
ReadFile : 21126
Comp : 13242
ReadFile : 1918485
Comp : 13509
--------------------------

なんかたまに早い時もありますね。

コピー処理はなんであんなに早いんですかね?(SHFileOperation内部ではReadFileを使ってない
のかな?)

ReadFileについて調べることにします。
ありがとうございました。

※もう少し情報ほしいので、まだ解決にチェックは付けません。


返信引用
Tome
 Tome
(@Tome)
ゲスト
結合: 18年前
投稿: 36
Topic starter  

申し訳ありません。
二回投稿してしまったみたいです。


返信引用
Tome
 Tome
(@Tome)
ゲスト
結合: 18年前
投稿: 36
Topic starter  

>> まあ、プログレスバーはコピーの前処理(比較)にプログレスバー使うのも大げさなんで、砂
> 時計カーソルとかにするのがいいんですかね・・・・
> それはアナタが(動きを見ながら)決めること。

その方法も含めて質問しています。
よろしくおねがいします。


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 1301
 

>>> まあ、プログレスバーはコピーの前処理(比較)にプログレスバー使うのも大げさなん
で、砂
>> 時計カーソルとかにするのがいいんですかね・・・・
>> それはアナタが(動きを見ながら)決めること。
> その方法も含めて質問しています。

は?

プログレスバー使うのが大げさかどうか訊かれても、そんなもんcase-by-caseでしょうに。
その待ちが利用者に不安/不満を与えるのであれば、それを軽減する策を講じるってだけ。

# それとも 絶対プログレスバーを表示せよ!って僕が書いたら従います?


返信引用
Tome
 Tome
(@Tome)
ゲスト
結合: 18年前
投稿: 36
Topic starter  

すいません。
質問が漠然としていました。

> 高速化を含めなにかいい方法はないでしょうか?

ReadFileが遅いことがわかったので、後は自分で調べてみます。
2,3日してまた解決しなかったらまた質問させていただきます。

あとは、最悪、10M以上はコピーできないなどの制限を付けてみるという方法もありかな、なんて
思いました。

ありがとうございました。


返信引用
固定ページ 1 / 2

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました