Способ сделать md5_file () быстрее? - PullRequest
10 голосов
/ 01 мая 2010

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

Ответы [ 8 ]

15 голосов
/ 01 мая 2010

Возможно, вы делаете это последовательно прямо сейчас. То есть выборка данных 1, данных процесса 1, данных выборки 2, данных процесса 2, ... и узким местом может быть передача данных.
Вы можете использовать curl_multi_exec () , чтобы немного распараллелить это. Либо зарегистрируйте CURLOPT_WRITEFUNCTION и обработайте каждый фрагмент данных (хитро, поскольку md5 () работает только с одним фрагментом данных).
Или проверьте уже готовые маркеры скручивания, а затем обработайте данные этого маркера.

edit: быстрый и грязный пример с использованием расширения хэша (который предоставляет функции для инкрементных хэшей) и 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);

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

0 голосов
/ 29 августа 2017

Объяснение того, что вы хотите сделать, поможет. Если вы хотите проверить файл с их MD5-хешами:

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

0 голосов
/ 21 сентября 2010

Я вижу очень хорошее предложение по оптимизации здесь . Это будет хорошо работать, особенно для больших файлов, где md5_file читает файл, а эта функция просто сравнивает второй байт каждого файла.

0 голосов
/ 01 мая 2010

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

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

0 голосов
/ 01 мая 2010

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

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

0 голосов
/ 01 мая 2010

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

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

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

0 голосов
/ 01 мая 2010

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

0 голосов
/ 01 мая 2010

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

...