Способ сделать md5_file () быстрее?

Я в настоящее время использую md5_file() пробежать приблизительно 15 URL и проверить их хеши MD5. Существует ли способ, которым я могу сделать это быстрее? Это берет слишком долго для пробежки всех их.

10
задан Moradnejad 29 August 2017 в 11:10
поделиться

6 ответов

Вероятно, сейчас вы делаете это последовательно. Т.е. получаете данные 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);

(не проверял результаты, хотя ... это только отправная точка)

15
ответ дан 3 December 2019 в 22:35
поделиться

№ Поскольку это встроенная функция, ускорить ее невозможно.

Но если ваш код загружает файлы до того, как их выполняет MD5, возможно, вы сможете оптимизировать ваши загрузки, чтобы они были быстрее. Вы также можете увидеть небольшое увеличение скорости, установив размер файла (используя ftruncate) перед его записью, если вы заранее знаете размер.

Кроме того, если файлы достаточно малы, чтобы их можно было хранить в памяти, и они уже есть в памяти (потому что они были загружены или читаются для какой-либо другой цели), вы можете использовать md5 для работать с ним в памяти, а не в md5_file , что требует повторного чтения с диска.

0
ответ дан 3 December 2019 в 22:35
поделиться

Алгоритм md5 работает настолько быстро, насколько это возможно, а получение урлов происходит настолько быстро, насколько это возможно (медленно, если файлы огромные или у вас медленное соединение). Так что нет. Вы не можете сделать это быстрее.

0
ответ дан 3 December 2019 в 22:35
поделиться

Ну, очевидно, что вы не можете ничего сделать с md5_file(), чтобы сделать быстрее, однако, вы можете использовать некоторые микро-оптимизации или рефакторинг кода, чтобы получить некоторый прирост скорости, но опять же, вы не можете ускорить встроенную функцию md5_file().

0
ответ дан 3 December 2019 в 22:35
поделиться

Предположительно вы проверяете одни и те же URL в течение определенного периода времени? Не могли бы вы проверить последние измененные заголовки URL-адреса? Если проверяемая страница не изменилась, нет необходимости повторно вычислять MD5.

Вы также можете запрашивать страницы асинхронно, чтобы их можно было обрабатывать параллельно, а не последовательно, что должно ускорить процесс.

0
ответ дан 3 December 2019 в 22:35
поделиться

Скорость алгоритма MD5 линейна. Чем больше ввод, тем больше времени потребуется, поэтому, если файл большой, вы мало что можете сделать.

Как уже предположил VolkerK, проблема, скорее всего, не в хешировании md5, а в получении и чтении файла по сети.

0
ответ дан 3 December 2019 в 22:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: