私は現在md5_file()
、約15のURLを実行し、それらのMD5ハッシュを検証するために使用しています。これをより速くする方法はありますか?それらすべてを実行するには時間がかかりすぎます。
8 に答える
おそらくあなたは今それを順番にやっています。つまり、データのフェッチ1、データの処理1、データのフェッチ2、データの処理2、...であり、ボトルネックはデータ転送である可能性があります。curl_multi_exec()
を
使用して、それを少し並列化することができます。CURLOPT_WRITEFUNCTIONを登録し、データの各チャンクを処理します(md5()はデータのチャンクを1つだけ処理するため、注意が必要です)。
または、すでに終了しているカールハンドルを確認してから、そのハンドルのデータを処理します。
編集:ハッシュ拡張(インクリメンタルハッシュの関数を提供する)とphp5.3 +クロージャーを使用したクイック&ダーティな例:
$urls = array(
'http://stackoverflow.com/',
'http://sstatic.net/so/img/logo.png',
'http://www.gravatar.com/avatar/212151980ba7123c314251b185608b1d?s=128&d=identicon&r=PG',
'http://de.php.net/images/php.gif'
);
$data = array();
$fnWrite = function($ch, $chunk) use(&$data) {
foreach( $data as $d ) {
if ( $ch===$d['curlrc'] ) {
hash_update($d['hashrc'], $chunk);
}
}
};
$mh = curl_multi_init();
foreach($urls as $u) {
$current = curl_init();
curl_setopt($current, CURLOPT_URL, $u);
curl_setopt($current, CURLOPT_RETURNTRANSFER, 0);
curl_setopt($current, CURLOPT_HEADER, 0);
curl_setopt($current, CURLOPT_WRITEFUNCTION, $fnWrite);
curl_multi_add_handle($mh, $current);
$hash = hash_init('md5');
$data[] = array('url'=>$u, 'curlrc'=>$current, 'hashrc'=>$hash);
}
$active = null;
//execute the handles
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
while ($active && $mrc == CURLM_OK) {
if (curl_multi_select($mh) != -1) {
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
}
foreach($data as $d) {
curl_multi_remove_handle($mh, $d['curlrc']);
echo $d['url'], ': ', hash_final($d['hashrc'], false), "\n";
}
curl_multi_close($mh);
(ただし、結果は確認していません...これは出発点にすぎません)
MD5アルゴリズムの速度は線形です。入力が大きいほど時間がかかるので、ファイルが大きい場合、実際にできることはあまりありません。
さて、VolkerKがすでに示唆しているように、問題はおそらくmd5ハッシュではなく、ネットを介してファイルを取得して読み取ることです。
md5アルゴリズムは可能な限り高速であり、URLのフェッチは可能な限り高速です(ファイルが大きい場合や接続が遅い場合は低速です)。だからいいえ。あなたはそれを速くすることはできません。
もちろん、速度を上げるために何もすることはできませんがmd5_file()
、いくつかのマイクロ最適化またはコードのリファクタリングを使用して速度を上げることはできますが、組み込み関数を高速化することはできませんmd5_file()
。
いいえ。これは組み込み関数であるため、高速化する方法はありません。
ただし、コードがファイルをMD5する前にダウンロードしている場合は、ダウンロードを最適化して高速化できる可能性があります。また、事前にサイズがわかっている場合は、ファイルを書き込む前にファイルのサイズを設定することで(ftruncateを使用して)速度がわずかに向上する場合があります。
また、ファイルがメモリに保持できるほど小さく、すでにメモリにある場合(ダウンロードされているか、他の目的で読み取られているため)、必要なファイルではなく、メモリ内でファイルを操作するために使用できますmd5
。md5_file
ディスクから再度読み取られます。
おそらく、ある期間にわたって同じURLをチェックしていますか?URLの最後に変更されたヘッダーを確認できますか?チェック対象のページが変更されていない場合は、MD5を再計算する必要はありません。
また、ページを非同期でリクエストして、ページをシリアルではなくパラレルで処理できるようにすることもできます。これにより、ページが高速化されます。
ここで最適化の非常に良い提案があります。これは、md5_fileがファイルを読み取り、この関数が各ファイルの2番目のバイトを比較している大きなファイルで特にうまく機能します。
あなたがやりたいことを説明することは助けになるでしょう。MD5ハッシュを使用してファイルを検証する場合:
衝突攻撃を受けやすいため、安全な方法ではありません。複数のハッシュを使用するか(ファイルを分割するなど)、他のハッシュメソッドを使用する必要があります。