我目前使用md5_file()
来验证约15个URL的MD5哈希值。有没有一种方法可以使这个过程更快?运行所有URL需要太长时间了。
可能你目前是按顺序执行。即获取数据1,处理数据1,获取数据2,处理数据2...这样数据传输可能会成为瓶颈。
你可以使用curl_multi_exec()来进行并行处理。
可以注册一个CURLOPT_WRITEFUNCTION并处理每个数据块(这有些棘手,因为md5()仅适用于精确的一个数据块)
或者检查已经完成的curl句柄,然后处理该句柄的数据。
编辑:快速且简单的示例使用哈希扩展(提供了增量哈希函数)和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);
(虽然我还没有检查结果...但这只是一个起点)
md5sum
CLI命令(例如exec('bash -c "md5sum file1 > file1.md5 &"')
)或使用类似PHP的pcntl_fork()来分叉多个调用md5_sum()来并行化md5部分。它们都有缺点,但在正确的上下文中,它们可能是最好的选择。 - Frank FarmerMD5算法已经非常快了,获取URL也已经尽可能地快(如果文件很大或者你的连接速度慢,则会变慢)。所以答案是否定的。你无法让它更快。
显然,您无法通过 md5_file()
做任何使其更快的操作。但是,您可以使用一些微优化或代码重构来获得一些速度提升,但您仍无法加速内置函数md5_file()
。
不行。由于这是一个内置函数,无法加快其速度。
但是,如果您的代码在进行MD5计算之前下载文件,可能可以优化下载速度。如果您事先知道文件的大小,可以在写入文件之前设置文件的大小(使用ftruncate),这样可能会略微提高速度。
此外,如果文件足够小以适应内存,并且您已经将它们保存在内存中(因为它们已被下载或正在被用于其他目的),那么您可以使用md5
在内存中操作它,而不是使用需要从磁盘重新读取的md5_file
。
假设您在一段时间内检查相同的URL?您可以检查URL的最后修改标头吗?如果正在检查的页面没有更改,则无需重新计算MD5。
您还可以异步请求页面,以便可以并行处理而不是串行处理,这应该可以加快速度。
MD5算法的速度是线性的。输入越大,花费的时间就越多,所以如果文件很大,你真的没有太多可以做的。
现在,正如VolkerK已经建议的那样,问题很可能不是MD5哈希,而是通过网络检索和读取文件。
解释你想要做什么会有所帮助。如果你想要使用MD5哈希值验证文件:
这不是一种安全的方法,因为它容易受到碰撞攻击的影响。你应该使用多个哈希值(也许通过分割文件)或者使用其他哈希方法。
md5_file('http://some.url/foo')
等函数来处理 15 个不同的 URL?这些“文件”有多大? - VolkerKmd5_file
不是瓶颈。此外,空文件的哈希值肯定是相同的。 - salathe