Я в настоящее время использую md5_file()
пробежать приблизительно 15 URL и проверить их хеши MD5. Существует ли способ, которым я могу сделать это быстрее? Это берет слишком долго для пробежки всех их.
Вероятно, сейчас вы делаете это последовательно. Т.е. получаете данные 1, обрабатываете данные 1, получаете данные 2, обрабатываете данные 2, ... и узким местом может быть передача данных.
Вы можете использовать curl_multi_exec(), чтобы немного распараллелить это.
Либо зарегистрировать CURLOPT_WRITEFUNCTION и обрабатывать каждый кусок данных (сложно, поскольку md5() работает ровно с одним куском данных).
Или проверить, не завершены ли уже обработчики curl, а затем обработать данные этого обработчика.
edit: quick&dirty example using the hash extension (which provides functions for incremental hashes) and a php5.3+ closure:
$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, возможно, вы сможете оптимизировать ваши загрузки, чтобы они были быстрее. Вы также можете увидеть небольшое увеличение скорости, установив размер файла (используя ftruncate) перед его записью, если вы заранее знаете размер.
Кроме того, если файлы достаточно малы, чтобы их можно было хранить в памяти, и они уже есть в памяти (потому что они были загружены или читаются для какой-либо другой цели), вы можете использовать md5
для работать с ним в памяти, а не в md5_file
, что требует повторного чтения с диска.
Алгоритм md5 работает настолько быстро, насколько это возможно, а получение урлов происходит настолько быстро, насколько это возможно (медленно, если файлы огромные или у вас медленное соединение). Так что нет. Вы не можете сделать это быстрее.
Ну, очевидно, что вы не можете ничего сделать с md5_file()
, чтобы сделать быстрее, однако, вы можете использовать некоторые микро-оптимизации или рефакторинг кода, чтобы получить некоторый прирост скорости, но опять же, вы не можете ускорить встроенную функцию md5_file()
.
Предположительно вы проверяете одни и те же URL в течение определенного периода времени? Не могли бы вы проверить последние измененные заголовки URL-адреса? Если проверяемая страница не изменилась, нет необходимости повторно вычислять MD5.
Вы также можете запрашивать страницы асинхронно, чтобы их можно было обрабатывать параллельно, а не последовательно, что должно ускорить процесс.
Скорость алгоритма MD5 линейна. Чем больше ввод, тем больше времени потребуется, поэтому, если файл большой, вы мало что можете сделать.
Как уже предположил VolkerK, проблема, скорее всего, не в хешировании md5, а в получении и чтении файла по сети.